ULOG_ACCTD学习总结

1.在ULOG_ACCTD源代码中使用了一个snprintf函数来实现动态的改变输出变量的位置。

Sprintf函数介绍(http://bernieyoo.spaces.live.com/

Ruby的sprintf格式与C语言的sprintf(3)基本相同。但还是有些差别: 它没有针对C特有类型的修饰符,如short或long等; 它包含2进制数的指示符(%b); 它不支持sprintf的方言式的语法。

下面就对ruby的sprintf格式进行详细的说明。

sprintf格式的规格如下所示。[]中的部分是可选的。

%[指定参数$][标识符][宽度][.精度]指示符

若想输出`%'本身时, 请这样`%%'处理。

下面就分别介绍一下各元素的用法。

标识符

标识符包括`#', `+', ` '(空格), `-'和`0'这5个。

#

使用2进制、8进制、16进制的指示符(`b', `o', `x', `X')时, 会分别添加"0b", "0", "0x", "0X"前缀。

p sprintf("%#b", 10) # => "0b1010"
p sprintf("%#o", 10) # => "012"
p sprintf("%#x", 10) # => "0xa"
p sprintf("%#X", 10) # => "0XA"

对于浮点数 (`f', `e', `E', `g', `G'), 则必定在输出中添加"."。

p sprintf("%.0f", 10) # => "10"
p sprintf("%#.0f", 10) # => "10."
p sprintf("%.0e", 10) # => "1e+01"
p sprintf("%#.0e", 10) # => "1.e+01"

`g', `G'除了具有上述特性外, 还会在末尾添加多余的0。

p sprintf("%.05g", 10) # => "10"
p sprintf("%#.05g", 10) # => "10.000"
+

使输出字符串带上符号。如果是正数的话, 就会添加`+'。它只对数值指示符(`d', `i', `b', `o', `x', `X', `u', `f', `e', `E', `g', `G')起作用。另外, 如果是`b', `o', `x', `X', `u'的话, 则会为负数添加`-'。

p sprintf("%d", 1)   # => "1"
p sprintf("%+d", 1)  # => "+1"

p sprintf("%x", -1)  # => "..f"  # ".." 表示f无限延续
p sprintf("%+x", -1) # => "-1"
' '(空格)

与`+'相同, 用空格来代替正号`+'。它只对数值指示符(`d', `i', `b', `o', `x', `X', `u', `f', `e', `E', `g', `G')起作用。

p sprintf("%d", 1)   # => "1"
p sprintf("%+d", 1)  # => "+1"
p sprintf("% d", 1)  # => " 1"

p sprintf("%x", -1)  # => "..f"
p sprintf("% x", 1)  # => " 1"
p sprintf("% x", -1) # => "-1"
-

使输出内容靠左. 若尚未指定宽度的话,则不起作用。

0

当输出内容靠右时, 使用`0'而并非空格来填充多余部分。

它只对数值指示符(`d', `i', `b', `o', `x', `X', `u', `f', `g', `G')起作用(对`e', `E'无效)

p sprintf("%010d", 10)
# => "0000000010"

与`#'一起使用时, 输出情况如下。

p sprintf("%#010x", 10)  # => "0x0000000a"
p sprintf("%#010o", 10)  # => "0000000012"
p sprintf("%#010b", 10)  # => "0b00001010"

它等同于下例。

p sprintf("%#10.8x", 10) # => "0x0000000a"
p sprintf("%#10.9o", 10) # => "0000000012"
p sprintf("%#10.8b", 10) # => "0b00001010"

通常情况下, 会输出如下内容。

p sprintf("%#10x", 10)   # => "       0xa"
p sprintf("%#10o", 10)   # => "       012"
p sprintf("%#10b", 10)   # => "    0b1010"

宽度

以非0数字开头的数串负责指定宽度。宽度是指生成字符串的宽度, 它不受后文中的精度的限制。

确定宽度时, 也会考虑标识符中附加的" ", "+","-", "0b", "0", "0x", "0X"的长度。

p sprintf("%#05x", 10) # => "0x00a"

宽度是指"必要的最小宽度". 若结果字符串的宽度超过指定宽度时, 指定宽度就会失效。

若将宽度指定为`*'时, 将从参数中取得宽度值。

p sprintf("%10s", "foo")    # => "       foo"
p sprintf("%*s", 10, "foo") # => "       foo"

精度

紧跟在"."后面的数串表示精度(若只有"."的话,则为".0")。若遇到整数的指示符(`d', `i', `b', `o', `x', `X', `u')的话,精度表示数值部分的长度。

p sprintf("%10.5d", 1)  # => "     00001"
p sprintf("%#10.5x", 1) # => "   0x00001"
p sprintf("%+10.5x", 1) # => "    +00001"

若遇到浮点数的指示符(`f')的话,它表示小数部分的位数。

p sprintf("%10.5f", 1)   # => "   1.00000"
p sprintf("%10.5f", 10)  # => "  10.00000"

若遇到浮点数的指示符(`e', `E', `g', `G')的话,它表示有效位数。

p sprintf("%10.5e", 1)   # => "1.00000e+00"
p sprintf("%10.5e", 10)  # => "1.00000e+01"
p sprintf("%10.5g",  10)  # => "        10"
p sprintf("%#10.5G", 10)  # => "    10.000"

如果是字符串指示符(`s', `p')的话,将会按照精度的规定来检查参数中的字符串长度,并切除多余部分。若将宽度和精度设为同值的话,则只输出参数字符串中的符合精度规定的部分。

p sprintf("%10.2s", "foo")  # => "        fo"

p sprintf("%5.5s", "foo")     # => # => "  foo"
p sprintf("%5.5s", "foobar")  # => # => "fooba"

若将精度设为`*'的话,将从参数中提取精度的值。

p sprintf("%.5s", "foobar")    # => "fooba"
p sprintf("%.*s", 5, "foobar") # => "fooba"

指示符

指示符指出参数的类型,且是必选的。大体说来它包括:

  • 表示字符串的指示符: `c', `s', `p'
  • 表示整数的指示符: `d', `i', `u', `b', `o', `x', `X',
  • 表示浮点数的指示符: `f', `g', `e', `E', `G'

这几类。

c

将参数的数值(0×255)看作是字符代码,并输出对应的字符。若参数并非数值、String、 nil, true或false的话,将尝试用to_int方法进行变换。

此时,只有标识符`-'和"宽度"的设定是有效的。

s

输出字符串。

若参数并非String对象的话,将使用to_s方法对其进行变换。

p

ruby 1.8 特性: 输出Object#inspect的结果。

p sprintf("%s", [1, 2, 3])      # => "123"
p sprintf("%p", [1, 2, 3])      # => "[1, 2, 3]"
d i

以10进制整数的形式输出参数中的数值。

若参数并非整数,则使用与Integer函数相同的规则将其变为整数。

u

将参数的数值看作是无符号整数,并以10进制整数的形式输出它。

p sprintf("%u", -1) # => "..4294967295"

上面的代码会输出 p ".." + 0xffff_ffff.to_s。

ruby 1.7 特性: 在version 1.7中,不会附加".."。若是'%u'的话,则将参数看作是定长整数。此时,对于负整数n来说

printf("%u", n)

printf("%d", n & ~(-1 << n.size*8))

是一个意思。

b o x X

分别以2进制、8进制、16进制、16进制(大写字母)字符串的形式输出整数。

若使用了`#' 标识符的话,则分别在前面添加"0b", "0", "0x", "0X"。

若没有使用`+', ` ' 标识符时,将在负数的前面(若有`#' 标识符,则在"0x"等的后面)添加".."。这表示最高位字符无限延伸,它采用了2的补数形式来表现负数。

p sprintf("%#b", 10)    # => "0b1010"
p sprintf("%#o", 10)    # => "012"
p sprintf("%#x", 10)    # => "0xa"

# 对负数添加".."
p sprintf("%#b", -1)    # => "0b..1"
p sprintf("%#o", -1)    # => "0..7"
p sprintf("%#x", -1)    # => "0x..f"

p sprintf("%10x", -1)   # => "       ..f"
p sprintf("%-10x", -1)  # => "..f       "

# 若指定了"精度"的话,则不会添加".."
p sprintf("%.10x", -1)  # => "ffffffffff"
f e E g G

`f' 以小数点形式(xxx.xxx)输出数值。

`e' 以指数形式(x.xxxe+xx)输出数值。

`g' 的情况比较特殊。当指数小于-4或者超出精度范围时,它采用`e'方式进行输出。除此之外,它采用`f'方式进行输出。另外,它会删除小数部分尾部的0。

大写字母指示符(`E', `G')会将输出中的字母变为大写形式。

p sprintf("%f", 1.0) # => "1.000000"
p sprintf("%e", 1.0) # => "1.000000e+00"
p sprintf("%g", 1.0) # => "1"

p sprintf("%f", 10.1) # => "10.100000"
p sprintf("%e", 10.1) # => "1.010000e+01"
p sprintf("%g", 10.1) # => "10.1"

p sprintf("%g", 10 ** 6)  # => "1e+06"
p sprintf("%g", 10 ** -5) # => "1e-05"

精度的缺省值为6。

若遇到无限大值或NaN(Not a Number)时,输出情况如下。

p sprintf("%f",  1.0/0)  # => "inf"
p sprintf("%f", -1.0/0)  # => "-inf"
p sprintf("%f",  0.0/0)  # => "nan"

p sprintf("%E",  1.0/0)  # => "INF"
p sprintf("%E", -1.0/0)  # => "-INF"
p sprintf("%E",  0.0/0)  # => "NAN"

指定参数

这部分的利用频率最低,所以放在最后。

nth$

表示将使用第nth个参数进行格式化操作。

p sprintf("%1$d, %1$x, %1$o", 10)
=> "10, a, 12"

p sprintf("%3$d, %2$x, %1$o", 1, 2, 3)
=> "3, 2, 1"

若您不想改变参数的顺序而只想改变格式的话,也可以使用它。

case ENV['LC_TIME']
when /^ja_JP/
   fmt = "%1$d年%2$d月%3$d日"
else
   fmt = "%2$02d/%03$2d/%1$02d"
end

p sprintf(fmt, 1, 4, 22)
=> "04/22/01"

您也可以先插入"*",然后借用参数来设定"宽度"和"精度"的值。

p sprintf("%5.2f", 1);              # => " 1.00"
p sprintf("%*.*f", 5, 2, 1);        # => " 1.00"
p sprintf("%1$*2$.*3$f", 1, 5, 2);  # => " 1.00"
  
    
    
ULOG-ACCTD学习总结
ULOG-ACCTD:
ulog-acctd is a userspace network accounting daemon which generates log files of network traffic for accounting purposes. It collects headers of IP packets that travel through the Linux 2.4+ netfilter. It writes accounting information to a log which can include protocol type, source and destination address, port numbers, byte and packet count, and incoming and outgoing interfaces.
 
Ulog-acctd是一个用户态的网络流量统计的守护进程。他可以生成的网络日志文件可以用来做统计目的。他主要是采集了通过Linux2.4+netfilter的IP数据包的头部信息。他可以把统计信息例如,协议类型,源目的IP,端口,字节数包数,流入流出接口等信息写入日志文件。
参考:
 
The log file format is configurable. For instance, it should be possible to directly generate files that contain SQL statements so that the raw accounting data can be fed into a DBMS.
Nonfeatures
ulog-acctd only collects, aggregates, and logs the all data it is fed by netfilter. If only traffic for specific networks needs to be collected, selection for this should be done in the netfilter rulesets, as ulog-acctd has no way to ignore some packets and log others.
ulog-acctd does not analyze them nor paint pretty pictures for traffic visualization. In the "one tool for one job" spirit of UNIX, Other tools should be used for these tasks.
net-acct
net-acct was developed by Ulrich Callmeier. The Mekafile hints that it can be used on Solaris (using libpcap). The Linux version uses the now obsolete packet interface at protocol level. (see ip(7)).
I had tried to implement support for the newer packet interface at device level (supported since Linux kernel versions 2.2, see packet(7)), but I found that it lost packets in high load situations. Patches against net-acctd are available on request.
ulog-acctd is based on net-acct and still shares some portions of the code.
 
日志文件的格式是可以配置的,所以他可以直接生成SQL语句,生成的日志文件可以直接导入到数据库中。
Netfilter
ulog-acctd relies on the kernel (more specific: Netfilter) to pipe the packet headers to user space. This has to be enabled by adding rules with the ULOG target to packet filtering tables.
The following example causes all packets that successfully pass the FORWARD table to be logged to ulog-acctd .
iptables --append FORWARD -j ULOG --ulog-nlgroup 1 --ulog-cprange 48 --ulog-qthreshold 50 --ulog-prefix "FORWARD"
Explaination:
  • -j ULOG causes the packet to passed to userspace in the first place.
  • --ulog-nlgroup GROUP specifies thet the packet be sent to multicast group GROUP. ulog-acctd has to be configured to listen to this group.
  • --ulog-cprange SIZE means that only the first SIZE bytes are copied to userspace. The default is to copy the whole packet, limiting the number of bytes should increase performance. However, when IP headers carry a lot of option fields, this may lead to the case that TCP, UDP, or ICMP headers are out of the copied range. ulog-acctd will log a warning to to the system log as well as the debug log in this case.
  • --ulog-qthreshold COUNT makes the kernel collect COUNT packets before sending the message containing these packets to userspace.
  • --ulog-prefix PREFIX causes a prefix string (max. 32 characters) to be passed along with the packet. This can for example be used for including hints for accounting systems.
For further information, see iptables(8).
Per default, configuration is done via the file /etc/ulog-acctd.conf . The following keywords are recognized:
  • multicast groups = LIST: LIST is a comma-separated list of multicast groups that ulog-acctd should listen to. Possible values are 1-32.
  • accounting file = FILENAME, dump file FILENAME, debug file FILENAME: Locations for the accounting file, dump file, debug log.
  • debug = LIST: LIST is a comma-spearated list of debug message types. Valid debug message types are: config, state, syscall, misc, statistics, signal, error, annoying.
  • accounting format = STRING: STRING is a format string with somewhat similar syntax to printf(3). The following directives are recognized and replaced in the output file.
%h
hostname
%t
timestamp
%p
protocol
%s
source IP
%S
source port
%d
destination IP
%D
destination port
%P
packets
%b
bytes
%i
incoming interface
%o
outgoing interface
%r
prefix
/t
tab
/n
newline
//
Literal /
/"
Literal "
/%
Literal %
%%
Literal %
  • empty interface = STRING: If no incoming or outgoing interface is passed for a packet, insert STRING instead.
  • empty prefix = STRING: If no ULOG-prefix is passed for a packet, insert STRING instead.
  • flush = TIME: The data that has been accumulated in a in-memory structure is written to the accounting file every TIME seconds.
  • fdelay = TIME: A certain record of traffic information may be written out after TIME seconds. This helps making the logfiles smaller since only one output record will be generated for related traffic
Example:
multicast groups=1
accounting file = /var/log/ulog-acctd/account.log
dump file =       /var/log/ulog-acctd/dump
debug file =      /var/log/ulog-acctd/debug.log
debug = error
accounting format = "%h/t%t/t%p/t%s/t%S/t%d/t%D/t%P/t%b/t/"%i/"/t/"%o/"/t/"%f/"/n"
flush = 30
fdelay = 30
 
The supplied accounting format string generates output records in the following form (all in one line, with a linefeed at the end):
judith 1032521454     6       192.168.42.11 110     192.168.215.71 1546    12      250113        "eth0" "eth1" "prefix"
The following format string will generate CISCO "ip accounting output-packets"-style output lines:
accounting format = "%s %d %P %b/n"
 
The lines will look like this:
192.168.42.11 192.168.215.71 12       250113
 
When not all types of information are collected, ulog-acctd will have to do fewer comparisions for each packet while collecting data. Records are smaller and likely fewer records will be written out. This will be the case especially if port information are not collected.
Invokation
ulog-acctd recognizes the following command-line parameters:
  • -d Switch on debugging
  • -c Specify alternative configuration file
  • -D Don't detach from terminal
·         To avoid rotating log files while ulog-acctd is logging accounting information, the SIGSTOP signal can be used to temporarily disable writing output records. SIGCONT re-enables logging.
Rotating log files
To avoid rotating log files while ulog-acctd is logging accounting information, the SIGSTOP signal can be used to temporarily disable writing output records. SIGCONT re-enables logging.
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值