12877


ubuntu14.04 に syslog-ng 3.5.3をインストールしました。

syslog-ngによるシステム負荷の削減のためflush_linesオプションでまとめてログを保存することを考えています。  
syslon-ngのインストールには成功し、動作もしています。

tail -f /var/log/messages でログを表示させて動作確認しています。

グローバルオプションに flush_lines(2)を追加して試したのですが、設定前と同じく即座にログが表示されてしまいます。

どなたかflush_linesを適切に設定し、ログ出力をまとめて実施する設定を教えてください。

実際に使用している設定は以下です。

[code]

    @version: 3.5
    @include "scl.conf"
    @include "`scl-root`/system/tty10.conf"
    
    # Syslog-ng configuration file, compatible with default Debian syslogd
    # installation.
    
    # First, set some global options.
    options { chain_hostnames(off); flush_lines(2); use_dns(no); use_fqdn(no);
          owner("root"); group("adm"); perm(0640); stats_freq(0);
          bad_hostname("^gconfd$");
    };
    
    ########################
    # Sources
    ########################
    # This is the default behavior of sysklogd package
    # Logs may come from unix stream, but not from another machine.
    #
    source s_src {
           system();
           internal();
    };
    
    # If you wish to get logs from remote machine you should uncomment
    # this and comment the above source line.
    #
    #source s_net { tcp(ip(127.0.0.1) port(1000)); };
    
    ########################
    # Destinations
    ########################
    # First some standard logfile
    #
    destination d_auth { file("/var/log/auth.log"); };
    destination d_cron { file("/var/log/cron.log"); };
    destination d_daemon { file("/var/log/daemon.log"); };
    destination d_kern { file("/var/log/kern.log"); };
    destination d_lpr { file("/var/log/lpr.log"); };
    destination d_mail { file("/var/log/mail.log"); };
    destination d_syslog { file("/var/log/syslog"); };
    destination d_user { file("/var/log/user.log"); };
    destination d_uucp { file("/var/log/uucp.log"); };
    
    # This files are the log come from the mail subsystem.
    #
    destination d_mailinfo { file("/var/log/mail.info"); };
    destination d_mailwarn { file("/var/log/mail.warn"); };
    destination d_mailerr { file("/var/log/mail.err"); };
    
    # Logging for INN news system
    #
    destination d_newscrit { file("/var/log/news/news.crit"); };
    destination d_newserr { file("/var/log/news/news.err"); };
    destination d_newsnotice { file("/var/log/news/news.notice"); };
    
    # Some `catch-all' logfiles.
    #
    destination d_debug { file("/var/log/debug"); };
    destination d_error { file("/var/log/error"); };
    destination d_messages { file("/var/log/messages"); };
    
    # The root's console.
    #
    destination d_console { usertty("root"); };
    
    # Virtual console.
    #
    destination d_console_all { file(`tty10`); };
    
    # The named pipe /dev/xconsole is for the nsole' utility.  To use it,
    # you must invoke nsole' with the -file' option:
    #
    #    $ xconsole -file /dev/xconsole [...]
    #
    destination d_xconsole { pipe("/dev/xconsole"); };
    
    # Send the messages to an other host
    #
    #destination d_net { tcp("127.0.0.1" port(1000) log_fifo_size(1000)); };
    
    # Debian only
    destination d_ppp { file("/var/log/ppp.log"); };
    
    ########################
    # Filters
    ########################
    # Here's come the filter options. With this rules, we can set which 
    # message go where.
    
    filter f_dbg { level(debug); };
    filter f_info { level(info); };
    filter f_notice { level(notice); };
    filter f_warn { level(warn); };
    filter f_err { level(err); };
    filter f_crit { level(crit .. emerg); };
    
    filter f_debug { level(debug) and not facility(auth, authpriv, news, mail); };
    filter f_error { level(err .. emerg) ; };
    filter f_messages { level(info,notice,warn) and 
                        not facility(auth,authpriv,cron,daemon,mail,news); };
    
    filter f_auth { facility(auth, authpriv) and not filter(f_debug); };
    filter f_cron { facility(cron) and not filter(f_debug); };
    filter f_daemon { facility(daemon) and not filter(f_debug); };
    filter f_kern { facility(kern) and not filter(f_debug); };
    filter f_lpr { facility(lpr) and not filter(f_debug); };
    filter f_local { facility(local0, local1, local3, local4, local5,
                            local6, local7) and not filter(f_debug); };
    filter f_mail { facility(mail) and not filter(f_debug); };
    filter f_news { facility(news) and not filter(f_debug); };
    filter f_syslog3 { not facility(auth, authpriv, mail) and not filter(f_debug); };
    filter f_user { facility(user) and not filter(f_debug); };
    filter f_uucp { facility(uucp) and not filter(f_debug); };
    
    filter f_cnews { level(notice, err, crit) and facility(news); };
    filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };
    
    filter f_ppp { facility(local2) and not filter(f_debug); };
    filter f_console { level(warn .. emerg); };
    
    ########################
    # Log paths
    ########################
    log { source(s_src); filter(f_auth); destination(d_auth); };
    log { source(s_src); filter(f_cron); destination(d_cron); };
    log { source(s_src); filter(f_daemon); destination(d_daemon); };
    log { source(s_src); filter(f_kern); destination(d_kern); };
    log { source(s_src); filter(f_lpr); destination(d_lpr); };
    log { source(s_src); filter(f_syslog3); destination(d_syslog); };
    log { source(s_src); filter(f_user); destination(d_user); };
    log { source(s_src); filter(f_uucp); destination(d_uucp); };
    
    log { source(s_src); filter(f_mail); destination(d_mail); };
    #log { source(s_src); filter(f_mail); filter(f_info); destination(d_mailinfo); };
    #log { source(s_src); filter(f_mail); filter(f_warn); destination(d_mailwarn); };
    #log { source(s_src); filter(f_mail); filter(f_err); destination(d_mailerr); };
    
    log { source(s_src); filter(f_news); filter(f_crit); destination(d_newscrit); };
    log { source(s_src); filter(f_news); filter(f_err); destination(d_newserr); };
    log { source(s_src); filter(f_news); filter(f_notice); destination(d_newsnotice); };
    #log { source(s_src); filter(f_cnews); destination(d_console_all); };
    #log { source(s_src); filter(f_cother); destination(d_console_all); };
    
    #log { source(s_src); filter(f_ppp); destination(d_ppp); };
    
    log { source(s_src); filter(f_debug); destination(d_debug); };
    log { source(s_src); filter(f_error); destination(d_error); };
    log { source(s_src); filter(f_messages); destination(d_messages); };
    
    log { source(s_src); filter(f_console); destination(d_console_all);
                        destination(d_xconsole); };
    log { source(s_src); filter(f_crit); destination(d_console); };
    
    # All messages send to a remote site
    #
    #log { source(s_src); destination(d_net); };
    
    ###
    # Include all config files in /etc/syslog-ng/conf.d/
    ###
    @include "/etc/syslog-ng/conf.d/*.conf"
    
[/code]


CC BY-SA 3.0
2015-07-30T10:46:49.433
12836
2015-07-31T08:24:04.730
704
question
linux
syslog-ng の flush_lines　オプションが効かない


syslog-ng 3.5.6 のソースコードを入手して調べてみた所、ある条件判定に不足がある様です。  
具体的には、`syslog-ng-3.5.6/lib/logwriter.c` の `log_writer_flush()` 関数です。

[code]

    gboolean
    log_writer_flush(LogWriter *self, LogWriterFlushMode flush_mode)
    {
                           :
    
      if (flush_mode >= LW_FLUSH_BUFFER || count == 0)
      {
        if (log_proto_client_flush(proto) == LPS_ERROR)
          return FALSE;
      }
    
[/code]

この `log_proto_client_flush()`
関数がログファイルへの書き込みを行っているのですが、直前の条件判定が不十分なのではないか、という事です。  
実際には syslog プロセスのメッセージバッファの大きさ(行単位)と `flush_lines`
の設定値を比較する処理が必要だと思われるのですが、`log_proto_client_flush()`
関数内でもその判定は行われていません。そこで、条件式の部分を以下の様に書き換えます。

[code]

    LogProtoFileWriter *w = (LogProtoFileWriter *)proto;
    if ( (w->buf_count >= w->buf_size) && (flush_mode >= LW_FLUSH_BUFFER || count == 0) )
      {
        if (log_proto_client_flush(proto) == LPS_ERROR)
          return FALSE;
      }
    
[/code]

`w->buf_count` がメッセージバッファの行数に当たります(実際には一行毎の構造体配列のサイズ)。`w->buf_size` は
`flush_lines` の設定値です。

ただ、`LogProtoFileWriter` 型(構造体)の定義が別のファイル(`syslog-
ng-3.5.6/modules/affile/logproto-file-writer.c`)で行われています。ヘッダファイルではないファイルを
`include` するのも何ですので、定義部分だけを `logwriter.c` ファイルにコピーします。

[code]

    typedef struct _LogProtoFileWriter
    {
      LogProtoClient super;
      guchar *partial;
      gsize partial_len, partial_pos;
      gint buf_size;
      gint buf_count;
      gint fd;
      gint sum_len;
      gboolean fsync;
      struct iovec buffer[0];
    } LogProtoFileWriter;
    
[/code]

変更後、コンパイル・リンクして syslog-ng を動作させると `flush_lines` が有効になりました。動作環境は Ubuntu Linux
15.04 です。


CC BY-SA 3.0
2015-07-31T08:24:04.730
12877
2015-07-31T08:24:04.730
12836
answer