qqxx6661 / log-record

使用注解优雅记录系统日志,操作日志,后端埋点等,支持SpEL表达式,自定义上下文,自定义函数,实体类DIFF等其他高阶处理。
Apache License 2.0
894 stars 165 forks source link

请教一个小问题😂 #84

Open sdhzwc opened 1 year ago

sdhzwc commented 1 year ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

sdhzwc commented 1 year ago

有没有相关实现demo参考一下

qqxx6661 commented 1 year ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

图里的只是使用的示例,并不是实际我的代码。

你要获取ip或者request对象,我理解你用常规的HttpServletRequest或者其他Spring或者web容器的就可以了,和操作日志框架本身没关系。

你网上搜类似的文章很多的:

https://www.cnblogs.com/ying-dong/p/12329085.html

sdhzwc commented 1 year ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

图里的只是使用的示例,并不是实际我的代码。

你要获取ip或者request对象,我理解你用常规的HttpServletRequest或者其他Spring或者web容器的就可以了,和操作日志框架本身没关系。

你网上搜类似的文章很多的:

https://www.cnblogs.com/ying-dong/p/12329085.html

我的意思其实是拦截到request对象,传递日志处理那一级进行统一处理,主要是想利用框架带来的便利

qqxx6661 commented 1 year ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

图里的只是使用的示例,并不是实际我的代码。 你要获取ip或者request对象,我理解你用常规的HttpServletRequest或者其他Spring或者web容器的就可以了,和操作日志框架本身没关系。 你网上搜类似的文章很多的: https://www.cnblogs.com/ying-dong/p/12329085.html

我的意思其实是拦截到request对象,传递日志处理那一级进行统一处理,主要是想利用框架带来的便利

其实比较灵活,举例几种方式:

第一种方式:在你能拿到Request的地方,直接用例如LogRecordContext.putVariable("ip", ip); ,放入框架的上下文,这样的好处是写入这个键值对后,在任何地方你都能拿到这个上下文,包括注解中的SpEL表达式里,也可以是在 你实现 IOperationLogGetService接口处理LogDTO的时候拿。坏处是这样会耦合业务代码中了,有一点耦合性。

第二种方式:在你IOperationLogGetService接口的实现里,通过上面说的从servlet里取或者从spring里面直接取到你要的request里的信息,比如IP地址等,拿到后直接写到logDTO的某个地方(由于IOperationLogGetService也是个spring托管的bean,所以你能正常使用spring的特性)。坏处是最好把消息处理的线程池关闭(log-record.thread-pool.enabled=false),改用主线程执行logDTO的处理,否则可能由于切换了线程,导致从servlet里取request或者一些其他方式取request会失效(因为请求进来的线程和我处理logDTO的线程已经不一样了,尽管我用了TransmittableThreadLocal,但不能保证所有父线程的上下文都集成到了子线程)

qqxx6661 commented 1 year ago
@Component
public class CustomFuncTestOperationLogGetService implements IOperationLogGetService {
    @Override
    public void createLog(LogDTO logDTO) {
        log.info("logDTO: [{}]", JSON.toJSONString(logDTO));
        // 处理logDTO的地方,你可以在这里统一写入request信息到logDTO的特定字段里,写入哪个字段就看你需求了
    }
}
sdhzwc commented 1 year ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

图里的只是使用的示例,并不是实际我的代码。 你要获取ip或者request对象,我理解你用常规的HttpServletRequest或者其他Spring或者web容器的就可以了,和操作日志框架本身没关系。 你网上搜类似的文章很多的: https://www.cnblogs.com/ying-dong/p/12329085.html

我的意思其实是拦截到request对象,传递日志处理那一级进行统一处理,主要是想利用框架带来的便利

其实比较灵活,举例几种方式:

第一种方式:在你能拿到Request的地方,直接用例如LogRecordContext.putVariable("ip", ip); ,放入框架的上下文,这样的好处是写入这个键值对后,在任何地方你都能拿到这个上下文,包括注解中的SpEL表达式里,也可以是在 你实现 IOperationLogGetService接口处理LogDTO的时候拿。坏处是这样会耦合业务代码中了,有一点耦合性。

第二种方式:在你IOperationLogGetService接口的实现里,通过上面说的从servlet里取或者从spring里面直接取到你要的request里的信息,比如IP地址等,拿到后直接写到logDTO的某个地方(由于IOperationLogGetService也是个spring托管的bean,所以你能正常使用spring的特性)。坏处是最好把消息处理的线程池关闭(log-record.thread-pool.enabled=false),改用主线程执行logDTO的处理,否则可能由于切换了线程,导致从servlet里取request或者一些其他方式取request会失效(因为请求进来的线程和我处理logDTO的线程已经不一样了,尽管我用了TransmittableThreadLocal,但不能保证所有父线程的上下文都集成到了子线程)

这两种方式我感觉有时候并不是最佳实践,我感觉好的方式是在LogDTO增加request对象,方便用户进行个性化处理

sdhzwc commented 1 year ago
@Component
public class CustomFuncTestOperationLogGetService implements IOperationLogGetService {
    @Override
    public void createLog(LogDTO logDTO) {
        log.info("logDTO: [{}]", JSON.toJSONString(logDTO));
        // 处理logDTO的地方,你可以在这里统一写入request信息到logDTO的特定字段里,写入哪个字段就看你需求了
    }
}

我现在使用的是1.5.1版本,返回值已经是布尔了 /**

}

qqxx6661 commented 1 year ago
@Component
public class CustomFuncTestOperationLogGetService implements IOperationLogGetService {
    @Override
    public void createLog(LogDTO logDTO) {
        log.info("logDTO: [{}]", JSON.toJSONString(logDTO));
        // 处理logDTO的地方,你可以在这里统一写入request信息到logDTO的特定字段里,写入哪个字段就看你需求了
    }
}

我现在使用的是1.5.1版本,返回值已经是布尔了 /**

  • SPI:操作日志本地处理 */ public interface IOperationLogGetService { /**

    • 自定义日志监听
    • @param logDTO 日志传输实体 */ boolean createLog(LogDTO logDTO) throws Exception;

}

这个我改下,文档没更新

qqxx6661 commented 1 year ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

图里的只是使用的示例,并不是实际我的代码。 你要获取ip或者request对象,我理解你用常规的HttpServletRequest或者其他Spring或者web容器的就可以了,和操作日志框架本身没关系。 你网上搜类似的文章很多的: https://www.cnblogs.com/ying-dong/p/12329085.html

我的意思其实是拦截到request对象,传递日志处理那一级进行统一处理,主要是想利用框架带来的便利

其实比较灵活,举例几种方式: 第一种方式:在你能拿到Request的地方,直接用例如LogRecordContext.putVariable("ip", ip); ,放入框架的上下文,这样的好处是写入这个键值对后,在任何地方你都能拿到这个上下文,包括注解中的SpEL表达式里,也可以是在 你实现 IOperationLogGetService接口处理LogDTO的时候拿。坏处是这样会耦合业务代码中了,有一点耦合性。 第二种方式:在你IOperationLogGetService接口的实现里,通过上面说的从servlet里取或者从spring里面直接取到你要的request里的信息,比如IP地址等,拿到后直接写到logDTO的某个地方(由于IOperationLogGetService也是个spring托管的bean,所以你能正常使用spring的特性)。坏处是最好把消息处理的线程池关闭(log-record.thread-pool.enabled=false),改用主线程执行logDTO的处理,否则可能由于切换了线程,导致从servlet里取request或者一些其他方式取request会失效(因为请求进来的线程和我处理logDTO的线程已经不一样了,尽管我用了TransmittableThreadLocal,但不能保证所有父线程的上下文都集成到了子线程)

这两种方式我感觉有时候并不是最佳实践,我感觉好的方式是在LogDTO增加request对象,方便用户进行个性化处理

request还是偏业务一点的概念,个人认为不太适合提升成一个LogDTO的属性。另外一个原因如果增加request字段,框架就必须帮用户完成request的获取,这点工作量就大了,无法覆盖完全,毕竟request的概念就很广。

sdhzwc commented 1 year ago

87 这是我的想法实现 这样就不用维护request对象了,而且用户也可以进行自定义操作

例如 1、实现接口IOperatorService ,对request对象操作(我们操作的时候request对象都是有效,只有异步写出会失效),放入logDTO.setExtra()字段,日志那一层进行具体封装自己的pojo,代码也就没有侵入性了

@Slf4j
@Service
public class IOperatorServiceImpl implements IOperatorService {
    @Override
    public void operatorServletRequestAttributes(ServletRequestAttributes servletRequestAttributes, LogDTO logDTO) {

        HttpServletRequest request = servletRequestAttributes.getRequest();
        Map<String, String[]> parameterMap = request.getParameterMap();
        String contextPath = request.getContextPath();
        String method = request.getMethod();
        JSONObject map = new JSONObject();
        map.put("parameterMap", parameterMap);
        map.put("contextPath",contextPath);
        map.put("method",method);

        logDTO.setExtra(JSON.toJSONString(map));
    }
}
zpdlut commented 4 months ago

获取请求ip地址或者request对象,您是怎么传递的 我看图片当中也提到了访问ip

图里的只是使用的示例,并不是实际我的代码。 你要获取ip或者request对象,我理解你用常规的HttpServletRequest或者其他Spring或者web容器的就可以了,和操作日志框架本身没关系。 你网上搜类似的文章很多的: https://www.cnblogs.com/ying-dong/p/12329085.html

我的意思其实是拦截到request对象,传递日志处理那一级进行统一处理,主要是想利用框架带来的便利

其实比较灵活,举例几种方式:

第一种方式:在你能拿到Request的地方,直接用例如LogRecordContext.putVariable("ip", ip); ,放入框架的上下文,这样的好处是写入这个键值对后,在任何地方你都能拿到这个上下文,包括注解中的SpEL表达式里,也可以是在 你实现 IOperationLogGetService接口处理LogDTO的时候拿。坏处是这样会耦合业务代码中了,有一点耦合性。

第二种方式:在你IOperationLogGetService接口的实现里,通过上面说的从servlet里取或者从spring里面直接取到你要的request里的信息,比如IP地址等,拿到后直接写到logDTO的某个地方(由于IOperationLogGetService也是个spring托管的bean,所以你能正常使用spring的特性)。坏处是最好把消息处理的线程池关闭(log-record.thread-pool.enabled=false),改用主线程执行logDTO的处理,否则可能由于切换了线程,导致从servlet里取request或者一些其他方式取request会失效(因为请求进来的线程和我处理logDTO的线程已经不一样了,尽管我用了TransmittableThreadLocal,但不能保证所有父线程的上下文都集成到了子线程)

目前还是只有这两种方式吗?