如何充当系统日志接收器?

Posted

技术标签:

【中文标题】如何充当系统日志接收器?【英文标题】:Howto act as a syslog receiver? 【发布时间】:2018-04-03 13:40:25 【问题描述】:

我想成为特定 syslog 日志的接收者。因此,从一个程序中收集所有系统日志消息并将其推送给用户。

有没有一种方法可以让我在 syslog 上“订阅”一个单元的日志消息?

除了看文件等等。

【问题讨论】:

【参考方案1】:

在我的例子中,它用于 rsyslog,可以通过 omuxsock 模块完成。 omuxsock == "输出模块 u​​nix 套接字" 这是 rsyslog 的一部分。 该模块将日志“写入”到需要由接收程序创建的 unix 套接字。 编辑: 下面是一个接收程序的例子:

#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

/*
this program acts as a receiver for rsyslog messages.
Just create a .conf file in /etc/rsyslog.d/ with the
following content:

$ModLoad omuxsock
$Template MyForwardTemplate,"%PRI%|%TIMESTAMP%|%HOSTNAME%|%syslogtag%|%msg%"
$OMUxSockSocket /tmp/mysock
*.* :omuxsock:;MyForwardTemplate

*/

vector<string> split(const string &s, char delim) 
    stringstream ss(s);
    string item;
    vector<string> tokens;
    while (getline(ss, item, delim)) 
        tokens.push_back(item);
    
    return tokens;


int main(int argc, char* argv[])

    const char *mysocketpath = "/tmp/mysock";
    struct sockaddr_un namesock;
    char buffer[512] =  0 ;
    int fd;
    int ret;

    namesock.sun_family = AF_UNIX;
    strncpy(namesock.sun_path, (char *)mysocketpath, sizeof(namesock.sun_path));

    cerr << "creating the socket ..." << endl;
    fd = ::socket(AF_UNIX, SOCK_DGRAM, 0);
    cerr << "binding it to the socket path ..." << endl;
    ret = ::bind(fd, (struct sockaddr *) &namesock, sizeof(struct sockaddr_un));
    if(ret != 0) 
        cerr << "bind error: " << strerror(errno) << endl;
        ret = 1;
        goto exit;
    

    do 
        memset(buffer, 0, 512);
        ret = ::read(fd, buffer, 512);
        if(ret > 0) 
            string s = buffer;
            vector<string> v = split(buffer, '|');

            if(v.size() == 5)
                cerr << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ", " << v[4] << endl;
            else 
                for(string s : v) 
                    cerr << s << ", ";
                
                cerr << endl;
            
        
     while(ret > 0);

exit:
    close(fd);
    unlink(mysocketpath);
    return ret;

【讨论】:

您能否发布一个示例,我已将 rsyslog 配置为将日志发送到 unix 套接字,但是当我创建 unix 套接字并收听它时。我看不到任何消息。 在我的答案中添加了一个示例 C++ 源代码,这对我有用。

以上是关于如何充当系统日志接收器?的主要内容,如果未能解决你的问题,请参考以下文章

如何接收系统日志消息并将其转换为字符串

基于flume的日志系统

PHPUnit 接收系统日志消息?

Ubuntu 系统日志记录如下问题,怎么解决

Java日志体系 —— 日志框架切换

MySQL中如何建立主从复制