log4j2配置固定内容(IP等)

需求: 记录日志时需要添加服务IP和服务编号(由UUID生成),便于运维人员在查看日志时定位到哪台服务器上的哪个服务。

基于spring web项目

1、 log4j2.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" monitorInterval="30">

    <Properties>
        <!-- 配置日志文件输出目录 -->
        <Property name="LOG_HOME">/home/logs</Property>
    </Properties>
    <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1.}:%L - IP:%X{ip}&amp;ID:%X{UUID}  %msg%xEx%n" />
        </Console>
        <!-- 按天第天备份一个日志 -->
        <RollingFile name="FILE" fileName="${LOG_HOME}/demo.log"
            filePattern="${LOG_HOME}/demo.log.%d{yyyy-MM-dd}.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1.}:%L - %X{ip}&amp;ID:%X{UUID}  %msg%xEx%n" />
            <Policies>
                <!-- 每24小时更新一次 -->
                <TimeBasedTriggeringPolicy modulate="true"
                    interval="24" />
                <SizeBasedTriggeringPolicy size="128KB" />
            </Policies>
            <!-- 最多备份10个 -->
            <DefaultRolloverStrategy max="10" />
        </RollingFile>
    </Appenders>
    <Loggers>

        <!--<Logger name="com.mosen" level="info">-->
            <!--<AppenderRef ref="FILE" />-->
        <!--</Logger>-->

        <Root level="info">
            <AppenderRef ref="CONSOLE" />
            <AppenderRef ref="FILE"></AppenderRef>
        </Root>
    </Loggers>
</Configuration>

pattern格式配置
%d{yyyy-MM-dd HH:mm:ss.SSS} “d”, “date” 时间格式
%-5level “p”, “level” 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%class{1.} “C”, “class” 类名,包名只有1位
%C{3} 获取类名前3级目录(包含类名)
%L “L”, “line” 输出行号
%M “M”, “method” 输出所在方法名
%m “m”, “msg”, “message” 日志文本
%xEx “xEx”, “xThrowable”, “xException” ExtendedThrowablePatternConverter
“ex”, “throwable”, “exception” ThrowablePatternConverter
“rEx”, “rThrowable”, “rException” RootThrowablePatternConverter
%n 换行

其他占位符有(部分):
%l “l”, “location” 输出语句所在的行数, 包括类名、方法名、文件名、行数 例如:hahaha.Log4j2Test.main(Log4j2Test.java:15)
%T “T”, “tid”, “threadId” 输出线程ID
%t “t”, “tn”, “thread”, “threadName” 输出当前线程名称
%tp “tp”, “threadPriority” 输出线程权级
%F “F”, “file” 输出所在的类文件名,如Log4j2Test.java
%logger “c”, “logger” 输出logger名称,LogManager.getLogger(Log4j2Test.class);中的名称,此处是hahaha.Log4j2Test
%N “N”, “nano” 纳秒
%sn “sn”, “sequenceNumber” 日志计数(全局)
%u “u”, “uuid” UUID(全局)
%X{ip} “X”, “mdc”, “MDC” MDC方式获取ip(等同于 %MDC{ip} 和 %mdc{ip} )
%x “x”, “NDC” NDC方式

2、 过滤器类
log4j2中用ThreadContext代替MDC

package demo;

import org.apache.logging.log4j.ThreadContext;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class ThreadContextFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            ThreadContext.put("UUID", StaticUUID.ID);    //StaticUUID是自己写的类,用于生成UUID常量。
            ThreadContext.put("ip", request.getLocalAddr());
            chain.doFilter(request, response);
        } finally {
        //清除ThreadContext,避免内存泄露
            ThreadContext.clearAll();
        }
    }

    @Override
    public void destroy() {

    }

}

3、 web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>

    <filter>
        <filter-name>log4jFilter</filter-name>
        <filter-class>demo.ThreadContextFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log4jFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>log4j2demo</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>log4j2demo</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

4、 Hello类测试

package demo;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Controller
public class Hello {
    public static Logger logger = LogManager.getLogger();

    @RequestMapping("/hello")
    public void hello(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.info("hello");
        request.getRequestDispatcher("index.jsp").forward(request, response);
    }
}

测试结果(多次刷新页面)
2017-06-28 21:04:59.013 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello

2017-06-28 21:06:48.364 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello

2017-06-28 21:06:49.203 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello

2017-06-28 21:06:49.900 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello
其中IP:0:0:0:0:0:0:0:1等同于127.0.0.1,由于是本地访问,就会出现这个值。用别的机器访问就会正常。

int start_ap(const char* ssid, const char* password){ int ret = 0; if (is_hostapd_running()) { console_run("killall hostapd"); } if (is_dnsmasq_running()) { console_run("killall dnsmasq"); } ret = creat_dnsmasq_file(); if (ret != 0) { printf("creat udhcpd file error\n"); return -1; } ret = creat_hostapd_file(ssid); if (ret != 0) { printf("creat hostapd file error\n"); return -1; } (void)console_run("ifconfig p2p0 up"); (void)console_run("ifconfig p2p0 10.201.126.1 netmask 255.255.255.0"); (void)console_run("route add default gw 10.201.126.1 p2p0"); char cmd1[50]; sprintf(cmd1, "dnsmasq -C %s --interface=p2p0", DNSMASQ_CONF_DIR); (void)console_run(cmd1); // (void)console_run("dnsmasq -C /data/dnsmasq.conf --interface=p2p0"); // LOG_DEBUG("qs,open dnsmasq"); // AP_open_flag = false; char cmd2[50]; sprintf(cmd2, "hostapd %s &", HOSTAPD_CONF_DIR); (void)console_run(cmd2); // (void)console_run("hostapd /data/hostapd.conf &"); // thread t1{[](){ // CTL_DEBUG << "qs,detect dnsmasq thread start"; // while(true){ // if(AP_open_flag == false){ // if (!is_dnsmasq_running()) { // CTL_DEBUG << "qs,detect dnsmasq status failed"; // char cmd3[50]; // sprintf(cmd3, "dnsmasq -C %s --interface=p2p0", DNSMASQ_CONF_DIR); // (void)console_run(cmd3); //// (void)console_run("dnsmasq -C /data/dnsmasq.conf --interface=p2p0"); // CTL_DEBUG << "qs,open dnsmasq"; // } // } // else{ // break; // } // // sleep(1); // } // CTL_DEBUG << "qs,detect dnsmasq thread over"; // } // }; // // t1.detach(); return ret; } 用这段代码适配一下
最新发布
04-02
<think>好的,我现在需要分析用户提供的C语言函数`int start_ap(const char* ssid, const char* password)`,并解释其功能和适配场景。首先,我要仔细阅读代码,理解每个步骤的作用。 首先,函数一开始检查`hostapd`和`dnsmasq`是否在运行,如果正在运行,就通过`console_run`执行命令终止它们。这可能是因为要重新配置这些服务,避免端口冲突或配置未生效的问题。 接下来,调用`creat_dnsmasq_file()`和`creat_hostapd_file(ssid)`来创建配置文件。这里需要注意的是,`creat_hostapd_file`只传入了`ssid`,而没有使用`password`参数,这可能意味着密码没有被正确配置,或者函数内部有其他处理,但根据用户提供的代码,这里可能存在一个潜在的问题,即生成的hostapd配置文件中可能缺少密码设置,导致创建的AP没有密码保护,存在安全隐患。 然后,代码通过`ifconfig`设置网络接口`p2p0`的IP地址和子网掩码,并添加默认网关。这里使用的是静态IP配置,确保AP的IP地址固定,方便后续的DHCP服务分配地址。 之后,构建并执行`dnsmasq`和`hostapd`的启动命令。`dnsmasq`负责DHCP和DNS服务,而`hostapd`用于创建无线接入点。这里使用了配置文件路径的宏定义,可能是为了灵活性,方便不同环境下的路径配置。 用户注释掉了一个线程部分,该线程用于监控`dnsmasq`的运行状态,如果检测到停止,就重新启动它。这可能是因为在某些情况下`dnsmasq`可能会意外终止,需要保持服务持续运行。但当前代码中这部分被注释掉了,可能还在测试阶段或者有其他替代方案。 在适配这段代码时,需要注意以下几点: 1. **硬件和驱动支持**:确保设备支持`p2p0`接口,并且无线网卡支持AP模式。可能需要检查内核模块是否正确加载。 2. **配置文件生成**:检查`creat_hostapd_file`是否正确处理了SSID和密码,确保生成的配置文件包含必要的安全设置,如WPA2加密。 3. **路径和权限**:确认`DNSMASQ_CONF_DIR`和`HOSTAPD_CONF_DIR`的路径是否正确,并且程序有权限写入这些配置文件以及执行相关命令。 4. **服务管理**:考虑是否需要加入守护进程或使用系统服务管理工具(如systemd)来管理`hostapd`和`dnsmasq`,以提高可靠性。 5. **错误处理**:当前代码中错误处理较为简单,可能需要更详细的错误日志,方便排查问题。 6. **安全性**:确保无线网络使用强密码和加密方式,避免使用开放网络。 另外,用户提供的函数中`password`参数未被使用,这需要确认是否是代码遗漏,还是`creat_hostapd_file`函数内部有其他方式获取密码。如果确实未使用,则创建的AP将没有密码,需提醒用户修改。 最后,根据不同的Linux发行版或嵌入式系统,命令路径或服务管理方式可能不同,需要针对目标环境进行调整。例如,某些系统可能使用`udhcpd`代替`dnsmasq`,或者`hostapd`的配置文件路径不同。需要确保所有命令和路径与目标系统兼容。</think>以下是对该代码的逐步解析和适配说明: $\textcolor{blue}{功能概述}$ 该函数用于在Linux系统上快速创建无线AP热点,主要流程包含: 1. 终止已有hostapd/dnsmasq进程 2. 生成配置文件 3. 配置网络接口 4. 启动DHCP和AP服务 $\textcolor{blue}{适配步骤}$ $\textbf{步骤1:环境验证}$ ```bash # 检查无线网卡AP模式支持 iw list | grep "AP" # 确认内核模块加载 lsmod | grep -E 'cfg80211|mac80211' ``` $\textbf{步骤2配置文件适配}$ 需实现以下两个函数: ```c // 示例伪代码 int creat_hostapd_file(const char* ssid) { FILE *fp = fopen(HOSTAPD_CONF_DIR, "w"); fprintf(fp, "interface=p2p0\n" "driver=nl80211\n" "ssid=%s\n" "hw_mode=g\n" "channel=6\n" "macaddr_acl=0\n" "auth_algs=1\n" "wpa=2\n" "wpa_passphrase=%s\n" // 注意原代码未使用password参数 "wpa_key_mgmt=WPA-PSK\n", ssid, password); // 需要修改函数参数 fclose(fp); return 0; } ``` $\textbf{步骤3:网络接口配置}$ ```c // 需要确认的硬件相关配置 console_run("ifconfig p2p0 up"); // 确认p2p0接口存在 console_run("ifconfig p2p0 10.201.126.1 netmask 255.255.255.0"); // IP地址段可自定义 ``` $\textbf{步骤4:服务管理优化}$ 建议添加守护进程管理: ```c // 修改原启动命令为 sprintf(cmd2, "hostapd -B %s", HOSTAPD_CONF_DIR); // -B参数后台运行 ``` $\textcolor{red}{关键问题修复}$ 1. 密码参数缺失问题: ```diff - ret = creat_hostapd_file(ssid); + ret = creat_hostapd_file(ssid, password); // 修改函数原型 ``` 2. 补充必要的错误检查: ```c if (system("which hostapd") != 0) { printf("hostapd not installed!"); return -1; } ``` $\textcolor{green}{适配验证脚本}$ ```bash # 服务状态检查 pgrep hostapd && pgrep dnsmasq # 网络接口验证 iw dev p2p0 info # 客户端连接测试 ping 10.201.126.1 ``` $\textcolor{blue}{典型应用场景}$ 1. 物联网设备配网模式 2. 嵌入式系统调试接口 3. 临时无线共享网络 4. 无路由器环境组网 建议增加iptables转发规则实现互联网共享: ```c console_run("iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE"); console_run("echo 1 > /proc/sys/net/ipv4/ip_forward"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值