在Linux是跑一個叫 syslogd/klogd 的demand去抓取kernel/user-space丟出來的除錯訊息。
- printk: kernel space丟出來的除錯訊息
printk("<6>Hello, world!\n");
- syslog: user space丟出來的訊息
#incluse
openlog(argv[0],LOG_PID,LOG_USER); syslog(LOG_INFO,"TEST SYSLOG\n"); closelog();
而 busybox 的 syslogd –R選項又可以負責將撈到的除錯訊息往網路(udp port 514)上丟。
- syslogd 所支援的命令,摘錄 -N用法。
$ busybox syslogd --help BusyBox v1.16.0 (2010-02-10 14:33:06 CST) multi-call binary. Usage: syslogd [OPTIONS] System logging utility. Note that this version of syslogd ignores /etc/syslog.conf. Options: -N rotated logs to keep (default:1, max=99, 0=purge) -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)
-
參考Source code。得知syslogd.c並不是用廣播的方式丟debug message,還是需要指定Server端 IP。
- host2sockaddr 負責dns/ip切換
- sendto 負責丟message
- G.remoteFD 就是 file handle
#if ENABLE_FEATURE_REMOTE_LOG static int try_to_resolve_remote(void) { if (!G.remoteAddr) { unsigned now = monotonic_sec(); if ((now - G.last_dns_resolve) < DNS_WAIT_SEC) return -1; G.last_dns_resolve = now; G.remoteAddr = host2sockaddr(G.remoteAddrStr, 514); if (!G.remoteAddr) return -1; } return socket(G.remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0); } #endif ... #if ENABLE_FEATURE_REMOTE_LOG if (G.remoteAddrStr) { if (-1 == G.remoteFD) { G.remoteFD = try_to_resolve_remote(); if (-1 == G.remoteFD) goto no_luck; } recvbuf[sz] = '\n'; sendto(G.remoteFD, recvbuf, sz+1, MSG_DONTWAIT, &G.remoteAddr->u.sa, G.remoteAddr->len); no_luck: ; } #endif
- 先以Linux實作(參考: http://www.abc.se/~m6695/udp.html)
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/time.h> #include <sys/wait.h> #include <errno.h> #define BUFLEN 512 #define NPACK 2 #define PORT 514 #define SRV_IP "192.168.0.105" void err_msg(char *s) { perror(s); exit(1); } int main(void) { struct sockaddr_in si_other; int s, i, slen=sizeof(si_other); char buf[BUFLEN]; if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) err_msg("socket"); memset((char *) &si_other, 0, sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons(PORT); if (inet_aton(SRV_IP, &si_other.sin_addr)==0) { fprintf(stderr, "inet_aton() failed\n"); exit(1); } for (i=0; i<NPACK; i++) { printf("Sending packet %d\n", i); sprintf(buf, "This is packet %d\n", i); if (sendto(s, buf, strlen(buf), 0, &si_other, slen)==-1) err_msg("sendto()"); } close(s); return 0; }
- 結果,將Filter選項設成 syslog
- 實作考量
- 能參考那邊的機制: printr/FileConsolePutChar
- 有需要作一個fifo的機制嗎,一次塞一個char,
在Win32這邊搭配的就是Wiki 這軟體就是負責去撈 syslogd 丟到網路上的除錯訊息。
【下載】
【使用】
(tbd)
【弄個自己的Syslogd】
(tbd)
【參考】
- php-syslog-ng http://code.google.com/p/php-syslog-ng/
- 目前Ubuntu 9.10已經使用 rsyslogd