前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 日志转发 syslog

Java 日志转发 syslog

原创
作者头像
dandelion1990
发布2024-02-06 01:04:30
1230
发布2024-02-06 01:04:30
举报

syslog服务器配置

配置rsyslog配置文件/etc/rsyslog.conf

rsyslog服务端接收

作为日志聚合服务,接受客户端发送过来的日志

开启UDP/TCP接收:

代码语言:properties
复制
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

配置日志接收规则:

代码语言:properties
复制
$template RemoteLogs,"/data/logs/%fromhost-ip%/%$YEAR%-%$MONTH%-%$DAY%.log"
:fromhost-ip, !isequal, "127.0.0.1" ?RemoteLogs
#& ~

rsyslog客户端发送

rsyslog也可以作为客户端向远程的rsyslog服务端转发日志

开启转发:

代码语言:properties
复制
# UDP转发
*.* @server_ip:514

# TCP转发
*.* @@server_ip:514

重启rsyslog服务

当rsyslog服务端或客户端配置完成后,重启服务使配置生效

代码语言:bash
复制
systemctl restart rsyslog
systemctl status rsyslog

配置支持TLS的rsyslog

安装依赖包

配置支持TLS的rsyslog需要安装以下依赖包

代码语言:bash
复制
yum install rsyslog-gnutls
yum install rsyslog
yum install gnutls-utils
yum install gnutls
生成密钥与证书
代码语言:bash
复制
# 生成根证书
certtool --generate-privkey --outfile ca-key.pem
certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca.pem

# 生成服务端密钥与证书
certtool --generate-privkey --outfile rslserver-key.pem --bits 2048
certtool --generate-request --load-privkey rslserver-key.pem --outfile request.pem
certtool --generate-certificate --load-request request.pem --outfile rslserver-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem

# 生成客户端密钥与证书
certtool --generate-privkey --outfile rslclient-key.pem --bits 2048
certtool --generate-request --load-privkey rslclient-key.pem --outfile request.pem
certtool --generate-certificate --load-request request.pem --outfile rslclient-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem

注意:输入证书信息时名字不要留空,不然后面Java中会报java.security.cert.CertificateParsingException: X.509 Certificate is incomplete: subject field is empty的错误

配置服务端接收TLS连接
代码语言:properties
复制
$DefaultNetstreamDriver gtls
$DefaultNetstreamDriverCAFile /root/tls/ca.pem
$DefaultNetstreamDriverCertFile /root/tls/rslserver-cert.pem
$DefaultNetstreamDriverKeyFile /root/tls/rslserver-key.pem

# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

$InputTCPServerStreamDriverAuthMode anon
$InputTCPServerStreamDriverMode 1
$ActionSendStreamDriverAuthMode x509/name
$ActionSendStreamDriverMode 1
$MaxOpenFiles 2048

配置客户端启用TLS连接

代码语言:properties
复制
$DefaultNetstreamDriver gtls

$DefaultNetstreamDriverCAFile /root/tls/private/ca.pem
$DefaultNetstreamDriverCertFile /root/tls/private/rslclient-cert.pem
$DefaultNetstreamDriverKeyFile /root/tls/private/rslclient-key.pem

$ActionSendStreamDriverPermittedPeer your.server.com # that should be your rsyslog server
$ActionSendStreamDriverMode 1 # run driver in TLS-only mode
$ActionSendStreamDriverAuthMode x509/name

注意:如果证书报错的话,可以改为$ActionSendStreamDriverAuthMode anon,即不需认证证书。

Log4j转发日志

Log4j 1.X转发syslog

这里Log4j的版本是1.2.17,配置log4j配置文件开启syslog转发

代码语言:plain
复制
log4j.rootLogger=INFO, console, fout, SYSLOG

log4j.appender.SYSLOG=org.apache.log4j.net.SyslogAppender
log4j.appender.SYSLOG.threshold=INFO
log4j.appender.SYSLOG.syslogHost={SYSLOG_HOST}
log4j.appender.SYSLOG.facility=LOCAL4
log4j.appender.SYSLOG.layout=org.apache.log4j.PatternLayout
log4j.appender.SYSLOG.layout.conversionPattern=%d{HH:mm:ss,SSS} %-5p %-60c %x - %m%n

需要在代码中导入系统变量

代码语言:java
复制
System.setProperty("SYSLOG_HOST", "127.0.0.1");

Log4j2中转发syslog

maven依赖

代码语言:xml
复制
<!--Log4j 2 dependencies-->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>${log4j2-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>${log4j2-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>${log4j2-version}</version>
</dependency>

配置模版

代码语言:xml
复制
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="5">
    <Properties>
        <Property name="console-layout">%d{HH:mm:ss} %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${console-layout}"/>
        </Console>
        <Syslog name="udp-syslog" host="localhost" port="514" protocol="UDP">
            <PatternLayout pattern="${console-layout}"/>
        </Syslog>
        <Syslog name="tcp-syslog" host="localhost" port="514" protocol="TCP">
            <PatternLayout pattern="${console-layout}"/>
        </Syslog>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="tcp-syslog"/>
        </Root>
    </Loggers>
</Configuration>

使用TLS转发日志

代码语言:xml
复制
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="5">
    <Properties>
        <Property name="console-layout">%d{HH:mm:ss} %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${console-layout}"/>
        </Console>
        <Syslog name="tls-syslog" host="localhost" port="6514">
            <SSL>
                <TrustStore location="truststore.jks"      password="KEYSTORE_PASSWORD"/>
            </SSL>
        </Syslog>
        <Syslog name="mtls-syslog" host="localhost" port="6514">
            <SSL>
                <KeyStore   location="log4j2-keystore.jks" password="KEYSTORE_PASSWORD"/>
                <TrustStore location="truststore.jks"      password="KEYSTORE_PASSWORD"/>
            </SSL>
        </Syslog>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="tls-syslog"/>
        </Root>
    </Loggers>
</Configuration>

其中,如果是单向TLS,只需要提供Rsyslog服务端的公钥证书,存入TrustStore中即可,配置中只需要指定TrustStore。如果需要双向TLS,则需要生成客户端的私钥与证书,存入KeyStore中。

读取证书与私钥

通过以下代码将base64编码的证书或私钥读入程序中

代码语言:java
复制
private static X509Certificate base64toCert(String base64String) throws CertificateException {
    byte[] decoded = Base64.getDecoder().decode(base64String);
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(decoded));
}

private static RSAPrivateKey base64toPrivateKey(String base64String) throws NoSuchAlgorithmException, InvalidKeySpecException {
    byte[] decoded = Base64.getDecoder().decode(base64String);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
    return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}

注意:私钥如果不是pkcs8格式的,上面代码无法读取,可以通过以下命令转换私钥格式

代码语言:bash
复制
certtool --to-p8 --load-privkey rslclient-key.pem --outfile rslclient-key-8.pem

将证书和私钥存入KeyStore

代码语言:java
复制
KeyStore keyStore = KeyStore.getInstance("jks");
String password = "yourpassword";
X509Certificate caCert = base64toCert(caBase64String);

// create new key store
keyStore.load(null, password.toCharArray());

// store certificate
keyStore.setCertificateEntry("cert name", caCert);

// store private key
X509Certificate[] certChain = new X509Certificate[2];
certChain[0] = cert;
certChain[1] = caCert;
Key privateKey = base64toPrivateKey(keyBase64String);
keyStore.setKeyEntry("key name", privateKey, password.toCharArray() , certChain);

// save to file
FileOutputStream fos = new FileOutputStream(trustStoreFileName);
keyStore.store(fos, password.toCharArray());

动态修改Log4j2配置

在配置文件中加上monitorInterval属性

代码语言:xml
复制
<Configuration monitorInterval="5" status="WARN">
</Configuration>

在程序中指定配置文件的位置,这样就会定期拉取最新的配置文件。注意,需要在所有的logger启动之前执行。

代码语言:java
复制
// set log4j2 configuration file location
LoggerContext context = (LoggerContext) LogManager.getContext(false);
File log4j2XmlFile = new File("log4j2.xml");
context.setConfigLocation(log4j2XmlFile.toURI());

接下来只需要修改"log4j2.xml"文件即可

修改XML文件

用Apache Commons Configuration来修改log4j2.xml配置文件

代码语言:java
复制
// 读取默认配置
File log4j2XmlFile = new File("log4j2.xml");
Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(XMLConfiguration.class)
        .configure(params.fileBased()
                .setFile(log4j2XmlFile));
Configuration config = builder.getConfiguration();

// 修改配置
String configNode = "Appenders.Syslog(1)"; // Appreders下有多个Syslog,所以需要指定第几个Syslog
config.addProperty(configNode + ".PatternLayout.[@pattern]", "${remote-layout}") // 为节点添加属性

// 保存配置
builder.save();

maven依赖

代码语言:xml
复制
<!--Apache Commons Configuration dependency-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-configuration2</artifactId>
    <version>${apache.commons.configuration-version}</version>
</dependency>
<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>
拷贝默认文件

可以用Apache Commons IO中的FileUtils.copyFile来拷贝文件

代码语言:java
复制
File originLog4j2XmlFile = new File("log4j2-origin.xml");
File log4j2XmlFile = new File("log4j2.xml");
FileUtils.copyFile(originLog4j2XmlFile, log4j2XmlFile);

maven依赖

代码语言:xml
复制
<!--Apache Commons IO dependency-->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

References

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • syslog服务器配置
    • rsyslog服务端接收
      • rsyslog客户端发送
        • 重启rsyslog服务
          • 配置支持TLS的rsyslog
            • 安装依赖包
            • 生成密钥与证书
            • 配置服务端接收TLS连接
        • Log4j转发日志
          • Log4j 1.X转发syslog
            • Log4j2中转发syslog
              • 使用TLS转发日志
                • 读取证书与私钥
                  • 将证书和私钥存入KeyStore
                    • 动态修改Log4j2配置
                      • 修改XML文件
                        • 拷贝默认文件
                    • References
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档