2012年3月31日土曜日

[C 语言] 信号 block unblock 处理

/*
 * Blocked calculation 执行过程中, 信号 kill -INT xxx 被屏蔽, 所以程序没有反映
 * 只有到信号被取消阻塞的时程序才会结束
 * 信号屏蔽只是将信号加入到信号阻塞集合之中, 并没有丢弃, 一旦信号屏蔽取消, 信号就会发生作用
 */

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char **argv)
{
    sigset_t intmask;
    int i, repeat_factor = 10;

    sigemptyset(&intmask);
    sigaddset(&intmask, SIGINT); // 添加 block 或 unblock 的信号
    // sigaddset(&intmask, SIGTERM);

    while(1) {
        sigprocmask(SIG_BLOCK, &intmask, NULL); // block
        fprintf(stderr,"SIGINT signal blocked\n");
        for(i = 0; i < repeat_factor; i++) {
            sleep(1);
            fprintf(stdout, "[%d] calculating...\n", i);
        }
        fprintf(stdout, "Blocked calculation is finished\n");

        sigprocmask(SIG_UNBLOCK, &intmask, NULL); // unblock
        fprintf(stdout, "SIGINT signal unblocked\n");
        for(i = 0; i < repeat_factor; i++) {
            sleep(1);
            fprintf(stdout, "[%d] calculating...\n", i);
        }
        fprintf(stdout, "Unblocked calculation is finished\n");
    }
    exit(0);
}

2012年3月30日金曜日

[C 语言] 在循环中 fork 子进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

void CreateSubProcess(int num);

int main(int argc, char *argv[])
{
    CreateSubProcess(5);
}

void CreateSubProcess(int num)
{
    pid_t pid;
    int i;
    for(i = 0; i < num; i++) {
        sleep(1);
        pid = fork();
        if(pid == 0 || pid == -1) // 子进程或错误时, 退出 for 循环继续执行下面的
            break;
    }
    if(pid == -1) {
        perror("fail to fork!\n");
        exit(1);
    } else if(pid == 0) {
        printf("child pid = %d, parent pid = %d\n", getpid(), getppid());
    } else {
        printf("all child's parent pid = %d\n", getpid(), getpid());
    }
    exit(0);
}

[C 语言] linux tcp socket 实例

1. 客户端
================================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define BUFFSIZE 32
void Die(char *mess)
{
    perror(mess);
    exit(1);
}
int main(int argc, char *argv[])
{
    int sock;
    struct sockaddr_in echoserver;
    char buffer[BUFFSIZE];
    unsigned int echolen;
    int received = 0;

    if (argc != 4) {
        fprintf(stderr, "USAGE: client <server_ip> <port> <word>\n");
        exit(1);
    }
    /* Create the TCP socket */
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        Die("Failed to create socket");
    }
    /* Construct the server sockaddr_in structure */
    memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */
    echoserver.sin_family = AF_INET;                  /* Internet/IP */
    echoserver.sin_addr.s_addr = inet_addr(argv[1]);  /* IP address */
    echoserver.sin_port = htons(atoi(argv[2]));       /* server port */
    /* Establish connection */
    if (connect(sock,
                (struct sockaddr *) &echoserver,
                sizeof(echoserver)) < 0) {
        Die("Failed to connect with server");
    }
    /* Send the word to the server */
    echolen = strlen(argv[3]);
    if (send(sock, argv[3], echolen, 0) != echolen) {
        Die("Mismatch in number of sent bytes");
    }
    /* Receive the word back from the server */
    fprintf(stdout, "Received: ");
    while (received < echolen) {
        int bytes = 0;
        if ((bytes = recv(sock, buffer, BUFFSIZE-1, 0)) < 1) {
            Die("Failed to receive bytes from server");
        }
        received += bytes;
        buffer[bytes] = '\0';        /* Assure null terminated string */
        fprintf(stdout, buffer);
    }
    fprintf(stdout, "\n");
    close(sock);
    exit(0);
}
================================================================================

2. 服务器
================================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define MAXPENDING 1    /* Max connection requests */
#define BUFFSIZE 32

void Die(char *mess)
{
    perror(mess);
    exit(1);
}

void HandleClient(int sock)
{
    char buffer[BUFFSIZE];
    int received = -1;
    /* Receive message */
    if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
        Die("Failed to receive initial bytes from client");
    }
    /* Send bytes and check for more incoming data in loop */
    while (received > 0) {
        /* Send back received data */
        if (send(sock, buffer, received, 0) != received) {
            Die("Failed to send bytes to client");
        }
        /* Check for more data */
        if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
            Die("Failed to receive additional bytes from client");
        }
    }
    close(sock);
}

int main(int argc, char *argv[])
{
    int serversock, clientsock, yes = 1;
    struct sockaddr_in echoserver, echoclient;

    if (argc != 2) {
        fprintf(stderr, "USAGE: server <port>\n");
        exit(1);
    }

    /* Create the TCP socket */
    if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        Die("Failed to create socket");
    }

    /* Construct the server sockaddr_in structure */
    memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */
    echoserver.sin_family = AF_INET;                  /* Internet/IP */
    echoserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* Incoming addr */
    echoserver.sin_port = htons(atoi(argv[1]));       /* server port */

    /* Set the reuse option to fix TIME_WAIT */
    setsockopt(serversock,
               SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));

    /* Bind the server socket */
    if (bind(serversock, (struct sockaddr *) &echoserver,
             sizeof(echoserver)) < 0) {
        Die("Failed to bind the server socket");
    }

    /* Listen on the server socket */
    if (listen(serversock, MAXPENDING) < 0) {
        Die("Failed to listen on server socket");
    }

    /* Run until cancelled */
    while (1) {
        unsigned int clientlen = sizeof(echoclient);
        /* Wait for client connection */
        if ((clientsock = accept(serversock,
                                 (struct sockaddr *) &echoclient,
                                 &clientlen)) < 0) {
            Die("Failed to accept client connection");
        }
        fprintf(stdout, "Client connected, ip: %s, port: %d\n",
                inet_ntoa(echoclient.sin_addr), echoclient.sin_port);
        HandleClient(clientsock);
    }
}
================================================================================

[C 语言] nslookup (gethostbyname)

/* Bare nslookup utility (w/ minimal error checking) */
#include <stdio.h>          /* stderr, stdout */
#include <stdlib.h>         /* exit() */
#include <unistd.h>         /* close(), write() */
#include <netdb.h>          /* hostent struct, gethostbyname() */
#include <arpa/inet.h>      /* inet_ntoa() to format IP address */
#include <netinet/in.h>     /* in_addr structure */

int
main(int argc, char **argv)
{
    struct hostent *host;     /* host information */
    struct in_addr h_addr;    /* Internet address */
    if (argc != 2) {
        fprintf(stderr, "USAGE: nslookup <inet_address>\n");
        exit(1);
    }
    if ((host = gethostbyname(argv[1])) == NULL) {
        fprintf(stderr, "(mini) nslookup failed on '%s'\n", argv[1]);
        exit(1);
    }
    h_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
    fprintf(stdout, "%s\n", inet_ntoa(h_addr));
    exit(0);
}

2012年3月29日木曜日

[工具使用] gdb 调试后台进程

1. ps 查询子进程 PID
$ ps x | grep pgpool
26258 pts/1    S      0:00 /usr/local/pgpool312/bin/pgpool -n
26259 pts/1    S      0:00 pgpool: wait for connection request <= 找到子进程 PID
26262 pts/1    S      0:00 pgpool: PCP: wait for connection request
26263 pts/1    S      0:00 pgpool: worker process
26267 pts/1    S      0:00 gdb /usr/local/pgpool312/bin/pgpool 26259
28887 pts/2    R+     0:00 grep pgpool

2. 启动 gdb, attach 子进程
$ gdb /usr/local/pgpool312/bin/pgpool 26259
或
$ gdb
$ gdb attach 26259

3. 显示 stack
$ gdb bt

4. 删除所有断点
$ gdb delete

5. 设置断点 (指定文件, 行号)
$ gdb b pool_process_query.c:243

6. 通过 pgpool 执行查询
$ psql -h localhost -p 9999 -c "select * from pgbench_accounts" -d postgres

7. 下一步
$ gdb n

8. 继续运行
$ gdb c

9. 显示变量内容
$ gdb p num_fds


$ gdb up
$ gdb down

[C 语言] daemon 守护进程

daemon (守护) 程序编写规则:
1. 程序运行后调用 fork, 并让父进程退出, 子进程获得一个新的进程 ID, 但继承了父进程的进程组 ID
2. 调用 setsid 创建一个新的 session, 使自己成为新 session 和新进程组的 leader, 并使进程没有控制终端 (tty)
3. 改变当前工作目录至根目录, 以免影响可加载文件系统, 或者也可以改变到某些特定的目录
4. 设置文件创建 mask 为 0, 避免创建文件时权限的影响
5. 关闭不需要的打开文件描述符, 因为 daemon 程序在后台执行, 不需要于终端交互, 通常就关闭 STDIN, STDOUT 和 STDERR, 其它根据实际情况处理, 另一个问题是 daemon 程序不能和终端交互, 也就无法使用printf方法输出信息了, 可以使用 syslog 机制来实现信息的输出, 方便程序的调试

程序运行后使用 ps 命令查看
$ ps axj | grep a.out
PPID   PID   PGID   SID   TTY  TPGID STAT   UID   TIME COMMAND
1      10118 10118  10118 ?       -1 Ss     505   0:00 ./a.out

例子:
================================================================================
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>

int main(void)
{
    if(daemon_init() == -1) {
        printf("can't fork self/n");
        exit(0);
    }
    openlog("daemontest", LOG_PID, LOG_USER);
    syslog(LOG_INFO, "program started.");
    signal(SIGTERM, sig_term); /* arrange to catch the signal */
    while(1) {
        sleep(1); /* put your main program here */
    }
    return(0);
}

int daemon_init(void)
{
    pid_t pid;
    if((pid = fork()) < 0)
        return(-1);
    else if(pid != 0)
        exit(0); /* parent exit */
    /* child continues */
    setsid(); /* become session leader */
    chdir("/"); /* change working directory */
    umask(0); /* clear file mode creation mask */
    close(0); /* close stdin */
    close(1); /* close stdout */
    close(2); /* close stderr */
    return(0);
}

void sig_term(int signo)
{
    if(signo == SIGTERM)
        /* catched signal sent by kill(1) command */
    {
        syslog(LOG_INFO, "program terminated.");
        closelog();
        exit(0);
    }
}
================================================================================

[LINUX 基础] top

1. top

-d N: 每 N 秒刷新一次
-n N: 刷新几次

[LINUX 基础] 显示部分行 (head tail sed)

1. 显示后 100 行
tail -n 100 filename
tail -n -100 filename

2. 显示从开头第 100 行开始的后面所有行
tail -n +100 filename

3. 显示开头 100 行
head -n 100 filename
head -n +100 filename

4. 从开头开始显示, 除去最后的 100 行
head -n 100 filename

5. 从第 3 行开始显示头 2 行
$ cat filename | tail -n +3 | head -n 2

6. 显示从第 2 行开始到第 3 行结束之间所有行
$ cat filename | head -n 3 | tail -n +2
$ sed -n '2,3p' filename

2012年3月28日水曜日

[LINUX 基础] diff 与 patch

diff
-r : ()递归, 将两个不同版本源代码目录中的所有对应文件进行比较, 包括子目录文件
-N : 确保补丁文件将正确地处理已经创建或删除文件的情况
-u : 统一格式创建补丁文件

patch
-p0: 针对于当前目录下的文件
-p1: 忽略掉 (补丁文件中的) 第一层目录, 从当前目录开始查找
-b : 备份要打补丁的原文件
-d : 当前工作目录设置为指定目录, 此时的 -p0 即代表此目录
-E : 如果发现了空文件, 那么就删除它
-R : 在补丁文件中的"新"文件和"旧"文件调换过来 (实际上就是给新版本打补丁, 让它变成老版本)

1. 单个文件打补丁

1-1. 制作 patch 文件 (形式: diff 旧版本 新版本)
$ diff –uN from-file to-file > to-file.patch

1-2. 给旧版本打补丁
$ patch -p0 -b < to-file.patch

1-3. 去除补丁, 恢复之前的旧版本
$ patch -p0 -RE < to-file.patch

2. 多文件

2-1. 制作 patch 文件
$ diff –uNr from-docu to-docu > to-docu.patch

2-2. 给旧版本打补丁
$ patch –p1 < to-docu.patch

2-3. 去除补丁, 恢复之前的旧版本
$ patch –R –p1

2012年3月26日月曜日

[项目管理] git 安装与使用

http://www.taocms.org/243.html

0-1. 分布式版本控制工具
0-2. 在一个不能连接网络的地方时, 仍然能够提交文件, 查看历史版本记录, 创建项目分支等
0-3. 仓库所在的目录就是你的日常工作目录, 没有服务器端和客户端之分
0-4. .git目录才是仓库, .git目录外的地方是你的工作目录

1. 安装 git 客户端
$ ./configure --prefix=/usr/local/git1794
$ make
$ sudo make install

2. [可选] 下载并安装 connect.c, 配置 ssh 通过 proxy
$ gcc connect -o connect
$ cat ~/.ssh/config
Host git.postgresql.org
ProxyCommand /home/go/bin/connect -S www.proxy.com %h %p

3. clone
3-1. 上传 /home/.ssh/id_rsa.pub 到 profile, 并且在相应 xxx 项目中登录帐号
     http://www.postgresql.org/community/signup
3-2. clone 代码到本地
$ git clone ssh://git@git.postgresql.org/xxx.git

4. 设置 git 本地用户信息
4-1. /etc/gitconfig 文件: 系统中对所有用户都普遍适用的配置, 若使用 git config 时用 --system 选项, 读写的就是这个文件
4-2. ~/.gitconfig 文件: 用户目录下的配置文件只适用于该用户, 若使用 git config 时用 --global 选项, 读写的就是这个文件
4-3. 工作目录 (当前项目) 中的 .git/config 文件的: 仅仅针对当前项目有效
4-4. 每一个级别的配置都会覆盖上层的相同配置, .git/config 会覆盖 /etc/gitconfig 中的同名变量

$ rm -fv ~/.gitconfig
$ rm -fv ~/.git/config
$ cd ?/git/src
$ sh git_init.sh
$ git config --list ($ git var -l)
$ cat git_init.sh
#!/bin/bash
git config branch.master.rebase true
git config branch.autosetuprebase always
git config user.name "Go"
git config user.email go@gmail.com
git config --global user.name "Go"
git config --global user.email go@gmail.com
# git config --global http.proxy http://www.proxy.com:80
================================================================================
1. 新建项目
$ cd pjname
$ git init

2. 克隆项目镜像到本地
git clone git://github.com/schacon/grit.git
git clone git://github.com/schacon/grit.git mygrit <- 指定新名称

3. 检查当前文件状态
$ git status

4. 更新到本地
$ git pull

5. 提交更改到本地库
$ git commit -m 'comments'

6. 上传至服务器
$ git push

7. 删除文件
$ rm -fv test.txt
$ git rm test.txt
$ git rm log/\*.log <- 删除目录 log 下所有以 .log 结尾的文件
$ git rm \*~ <- 递归删除当前目录及其子目录中所有 ~ 结尾的文件
$ git commit

8. 添加文件
$ git add *.c *.java
$ git commit -m 'add comments'

9. 更新并覆盖本地文件
$ git checkout test.txt

10. 几个 git 地址
[socksify] 有代理服务器时使用 socks 来通信
$ [socksify] git clone git://git.postgresql.org/git/postgresql.git
$ [socksify] git clone git://git.postgresql.org/git/pgpool2.git

[C 语言] yacc 与 lex

http://www.cppblog.com/lymons/archive/2009/02/02/72793.html

[Ruby] 日期函数

# utf-8
# ruby v1.9

require 'date'

YOUBI = ['Sun','Mon','Tues','Wed','Thur','Fri','Sat','Sun']

def usage(n)
    puts "Usage: make_sche_month YYYY MM Name1 Name2"
    exit n
end

if ARGV.size != 2 && ARGV.size != 4
   usage 1
end

d = Date.new(ARGV[0].to_i, ARGV[1].to_i, 1)

if d == nil
   usage 1
end

if ARGV[2] && ARGV[3]
  PERSON = [ARGV[2], ARGV[3]]
else
  PERSON = ['X','Y']
end

# print header
puts '|ym||xx:xx-xx:xx|xx:xx-xx:xx|comments|h'
month = d.month
token = 0
while true
  break if month != d.month

  if (d.cwday == 6)
    puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|-|-||"
  elsif (d.cwday == 7)
    puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|-|-||"
  #  token = (token + 1) % 2
  else
    if (token == 0)
      puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|#{PERSON[0]}|#{PERSON[1]}||"
    else
      puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|#{PERSON[1]}|#{PERSON[0]}||"
    end
  end
  d = d.succ

end

2012年3月25日日曜日

[JAVA] JDBC 数据库连接池

http://www.iteye.com/topic/96940
http://blog.sina.com.cn/s/blog_55d57a460100iq71.html
http://blog.csdn.net/mgoann/article/category/1086677

2012年3月22日木曜日

[JAVA] slf4j + log4j + log4jdbc

1. 下载并安装下列 jar 包
log4jdbc4-1.2.jar
log4j-1.2.16.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar
相关数据库的 x.jdbc.jar


2. 配置文件及位置
2-1. 将 log4j.proerties 加入到 classpath 中
2-2. 若不在 classpath 中, 则使用 JVM 系统变量
     -Dlog4j.configuration=file:/path/to/log4j.properties (Linux)
     -Dlog4j.configuration=file:/C:/path/to/log4j.properties (Windows)
2-3. 或使用如下 java 代码加载
final static Logger logger = LoggerFactory.getLogger(JdbcSqlLogTest.class);
static {
    PropertyConfigurator.configure("log4j.properties");
}


3. 使用

3-1. 编程方式
3-1-1. 修改代码中数据库驱动类名和连接字符串
// Class.forName("org.postgresql.Driver");
// Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:9120/go?user=go&password=go");
Class.forName("net.sf.log4jdbc.DriverSpy");
Connection conn = DriverManager.getConnection("jdbc:log4jdbc:postgresql://localhost:9120/go?user=go&password=go");

3-1-2. 包装正常的 Connection 数据库连接对象
Class.forName("org.postgresql.Driver");
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:9120/go?user=go&password=go");
Connection connProxy = new net.sf.log4jdbc.ConnectionSpy(conn);


================================================================================
# log4j.proerties sample
#
#   * DEBUG (lowest)
#   * INFO
#   * WARN (middle)
#   * ERROR
#   * FATAL (highest)
#
#   * %p --The priority of the logging event (debug, warn)
#   * %t --The name of the thread generating the event
#   * %c --The category of the logging event
#   * %m --message
#   * %n --newline character
#   * %d --date of the logging event ({yyyy-MM-dd HH:mm:ss,SSS})
#   * %l --Outputs the source code location information
#   * %C --Classname
#   * %F --Filename
#   * %L --Line number
#   * %M --Methodname
#   * %r --Number of milliseconds since the start of the vm
#
log4j.debug=false
log4j.rootLogger=ALL,stdout,mail
log4j.logger.logfile=ALL,logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=DEBUG
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p [%F:%4L - %M] - %m%n

log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.Threshold=DEBUG
log4j.appender.logfile.MaxFileSize=512KB
log4j.appender.logfile.MaxBackupIndex=10
log4j.appender.logfile.File=log/logdatei.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %-5p [%c] - %m%n

log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=OFF
log4j.appender.mail.BufferSize=32
log4j.appender.mail.SMTPHost=mail.gmx.net
log4j.appender.mail.SMTPUsername=qisbes@gmx.de
log4j.appender.mail.SMTPPassword=qis.bes
log4j.appender.mail.From=qisbes@gmx.de
log4j.appender.mail.to=ahrens@his.de
log4j.appender.mail.Subject=[DataImportExportTool] Error Alert
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} [%t] %-5p %c %x - %m%n

######################################
# Log4JDBC - Database-Driver-Logging #
######################################
log4j.logger.jdbc.audit=INFO,jdbc
log4j.additivity.jdbc.audit=false

! Log only JDBC calls to ResultSet objects
log4j.logger.jdbc.resultset=INFO,jdbc
log4j.additivity.jdbc.resultset=true

! Log only the SQL that is executed.
log4j.logger.jdbc.sqlonly=DEBUG,sql
log4j.additivity.jdbc.sqlonly=true

! Log timing information about the SQL that is executed.
log4j.logger.jdbc.sqltiming=DEBUG,sqltiming
log4j.additivity.jdbc.sqltiming=true

! Log connection open/close events and connection number dump
log4j.logger.jdbc.connection=DEBUG,connection
log4j.additivity.jdbc.connection=true

! the appender used for the JDBC API layer call logging above, sql only
log4j.appender.sql=org.apache.log4j.FileAppender
log4j.appender.sql.File=log/sql.log
log4j.appender.sql.Append=false
log4j.appender.sql.layout=org.apache.log4j.PatternLayout
log4j.appender.sql.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n%n

! the appender used for the JDBC API layer call logging above, sql timing
log4j.appender.sqltiming=org.apache.log4j.FileAppender
log4j.appender.sqltiming.File=log/sqltiming.log
log4j.appender.sqltiming.Append=false
log4j.appender.sqltiming.layout=org.apache.log4j.PatternLayout
log4j.appender.sqltiming.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n

! the appender used for the JDBC API layer call logging above
log4j.appender.jdbc=org.apache.log4j.FileAppender
log4j.appender.jdbc.File=log/jdbc.log
log4j.appender.jdbc.Append=false
log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbc.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n

! the appender used for the JDBC Connection open and close events
log4j.appender.connection=org.apache.log4j.FileAppender
log4j.appender.connection.File=log/connection.log
log4j.appender.connection.Append=false
log4j.appender.connection.layout=org.apache.log4j.PatternLayout
log4j.appender.connection.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
================================================================================