一种日志记录方法及系统与流程

文档序号:32663887发布日期:2022-12-24 00:23阅读:21来源:国知局
一种日志记录方法及系统与流程

1.本发明涉及计算机数据处理领域,特别涉及一种日志记录方法及系统。


背景技术:

2.市面上有不少的日志记录方式用来记录入参、处理时间和返回结果。但对于java web来说,当处理请求的方法以httpservletrequest为参数时,由于参数要通过自己调getparameter(“xxx”)等方法去获取,会出现记录不到参数的情况;当http请求为post请求,且不是form表单请求时,由于httpservletrequest的输入流只能读取一次,会出现记录不到请求体的参数的情况;还会出现记录不到此次请求的session信息的情况;当返回后只能记录到最终返回的页面,但不方便查看请求得到的结果;当参数中有httpservletresponse类型的对象时,且以该对象的输出流作为返回时,会出现记录不到返回结果的情况;如此,当基于java web时,现有的日志记录方式还存在记录不全的问题。


技术实现要素:

3.为了克服现有技术存在的缺陷,本发明的一个目的在于提供一种日志记录方法,以解决上述的问题;为了克服现有技术存在的缺陷,本发明的另一个目的在于提供一种日志记录系统,以解决上述的问题;本发明解决其技术问题所采用的技术方案是:一种日志记录方法,包括:请求生成步骤:java web容器根据接收到的http请求生成请求对象httpservletrequest和返回对象httpservletresponse;日志包装过滤步骤:日志包装过滤器logrequestwrapperfilte通过其自身的请求对象日志代理器将请求对象httpservletrequest包装成logrequestproxy类型的对象;日志包装过滤器logrequestwrapperfilte通过其自身的返回对象日志代理器将返回对象httpservletresponse包装成logresponseproxy类型的对象;日志记录拦截步骤:当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,获取logrequestproxy类型的对象对应的请求参数和请求时间并记录到所述请求对象日志代理器的logmap表中;当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,获取logresponseproxy类型的对象对应的返回值、方法名和当前session信息,并记录到所述返回对象日志代理器的logmap表中;值得说明的是,所述日志记录拦截步骤还包括:所述返回对象日志代理器从所述请求对象日志代理器的logmap表中获取请求参数和请求时间,并根据请求时间计算得到调用时间,其中调用时间=当前系统时间-请求时间;然后将返回值、方法名、当前session信息、参数params和调用时间记录到日志中;具体地,所述日志包装过滤步骤包括:初始化所述请求对象日志代理器,并构造函
数接收请求对象;读取请求对象httpservletrequest,并将请求对象httpservletrequest缓存在字节数组中;调用预先重写好的logrequestprox类型的public servletinputstream getinputstream()方法,将缓存在字节数组中的请求对象httpservletrequest重新生成输入流,得到logrequestproxy类型的对象;优选的,所述日志包装过滤步骤还包括:返回对象日志代理器在初始化时,构造函数接收返回对象;重写logresponseproxy类型的public void sendredirect(string location)方法和public printwriter getwriter()方法;当public void sendredirect(string location)方法被调用时,先将location参数作为请求的返回结果记录到返回对象日志代理器的logmap表中,然后再调用原始返回对象的public void sendredirect(string location)方法;当public printwriter getwriter()方法被调用时,先调用原返回对象的printwriter (),得到输出流对象printwriter后,将输出流对象封装成日志输出流对象logprintwriter;在logprintwriter类型中重写public void write(string s)方法时,先将参数记录到返回对象日志代理器的logmap表中,然后再调用原输出流对象printwriter对象的public void write(string s)方法完成返回;可选的,所述日志记录拦截步骤还包括:当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,通过prehandle方法,先读取url参数和表单参数,并记录到返回对象日志代理器的logmap表中;然后读取请求本参数,并记录到返回对象日志代理器的logmap表中;最后读取记录当前系统时间,将当前系统时间作为请求时间记录到返回对象日志代理器的logmap表中;其中,所述请求参数包括所述url参数、表单参数和请求本参数;当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,从prehandle方法的参数request的attributtes和modelandview的modle中获取所有页面模板参数,从prehandle方法的参数modelandview的view中获取页面模板路径,从参数request中获取路径参数,从参数request中取出当前session信息,从prehandle方法的参数handler中取出对应的方法名,并将当前session信息和方法名记录到所述返回对象日志代理器的logmap表中;值得说明的是,一种日志记录系统,包括请求生成模块、日志包装过滤模块、日志包装过滤模块和日志记录拦截模块;所述请求生成模块用于利用java web容器根据接收到的http请求生成请求对象httpservletrequest和返回对象httpservletresponse;所述日志包装过滤模块用于利用日志包装过滤器logrequestwrapperfilte通过其自身的请求对象日志代理器将请求对象httpservletrequest包装成logrequestproxy类型的对象;用于利用日志包装过滤器logrequestwrapperfilte通过其自身的返回对象日志代理器将返回对象httpservletresponse包装成logresponseproxy类型的对象;
所述日志记录拦截模块用于当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,获取logrequestproxy类型的对象对应的请求参数和请求时间并记录到所述请求对象日志代理器的logmap表中;用于当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,获取logresponseproxy类型的对象对应的返回值、方法名和当前session信息,并记录到所述返回对象日志代理器的logmap表中;具体地,所述日志记录拦截模块还用于利用所述返回对象日志代理器从所述请求对象日志代理器的logmap表中获取请求参数和请求时间,并根据请求时间计算得到调用时间,其中调用时间=当前系统时间-请求时间;然后将返回值、方法名、当前session信息、参数params和调用时间记录到日志中;可选的,所述日志包装过滤模块还用于初始化所述请求对象日志代理器,并构造函数接收请求对象;还用于读取请求对象httpservletrequest,并将请求对象httpservletrequest缓存在字节数组中;还用于调用预先重写好的logrequestprox类型的public servletinputstream getinputstream()方法,将缓存在字节数组中的请求对象httpservletrequest重新生成输入流,得到logrequestproxy类型的对象;优选的,所述日志包装过滤模块还用于返回对象日志代理器在初始化时,构造函数接收返回对象;还用于重写logresponseproxy类型的public void sendredirect(string location)方法和public printwriter getwriter()方法;还用于当public void sendredirect(string location)方法被调用时,先将location参数作为请求的返回结果记录到返回对象日志代理器的logmap表中,然后再调用原始返回对象的public void sendredirect(string location)方法;还用于当public printwriter getwriter()方法被调用时,先调用原返回对象的printwriter (),得到输出流对象printwriter后,将输出流对象封装成日志输出流对象logprintwriter;还用于在logprintwriter类型中重写public void write(string s)方法时,先将参数记录到返回对象日志代理器的logmap表中,然后再调用原输出流对象printwriter对象的public void write(string s)方法完成返回;值得说明的是,所述日志记录拦截模块还用于当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,通过prehandle方法,先读取url参数和表单参数,并记录到返回对象日志代理器的logmap表中;还用于读取请求本参数,并记录到返回对象日志代理器的logmap表中;还用于读取记录当前系统时间,将当前系统时间作为请求时间记录到返回对象日志代理器的logmap表中;其中,所述请求参数包括所述url参数、表单参数和请求本参数;还用于当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,从prehandle方法的参数request的attributtes和modelandview的modle中获取所有页面模板参数,从prehandle方法的参数modelandview的view中获取页面模板路径,从参数request中获取路径参数,从参数request中取出当前session信息,从prehandle方法的参数handler中取出对应的方法名,并将当前session信息和方法名记录到所述返回对象日志代理器的logmap表中;
本发明的有益效果在于:通过所述日志记录方法,就能从所述对象日志代理器的logmap表中获取到请求参数和请求时间,从所述返回对象日志代理器的logmap表中获取到返回值、方法名和当前session信息,并记录到日志中,如此,得到的日志全面,而不会缺失。
附图说明
4.图1为本发明的一个实施例中日志记录方法的流程图;图2为本发明的一个实施例中日志包装过滤器logrequestwrapperfilte的结构框图;图3为本发明的一个实施例中请求对象日志代理器和返回对象日志代理器的结构框图;图4为本发明的一个实施例中日志记录拦截器loginterceptor的结构框图;图5是本发明的一个实施例中日志记录系统的系统框图;图6是本发明的一个实施例中java web容器的结构框图。
具体实施方式
5.下面结合附图对本发明的具体实施方式作进一步说明。在此需要说明的是,对于这些实施方式的说明用于帮助理解本发明,但并不构成对本发明的限定。此外,下面所描述的本发明各个实施方式中所涉及的技术特征只要彼此之间未构成冲突就可以相互组合;如图1-6所示,一种日志记录方法,包括:请求生成步骤:java web容器根据接收到的http请求生成请求对象httpservletrequest和返回对象httpservletresponse;在本实施例中,请求对象httpservletrequest和是返回对象httpservletresponse均为java web容器的标准类型;对于请求对象httpservletrequest,该类型的对象request代表了此次请求,它包含有此次请求的所有信息;当请求是post请求时,请求参数此时是放在请求体里。如果该post请求是form表单请求,java web容器会自动解析到parameters(参数量)里;如果该post请求不是form表单请求,需要自己或由springmvc框架读取request中的输入流(inputstream);该输入流只能读取一次;日志包装过滤步骤:日志包装过滤器logrequestwrapperfilte通过其自身的请求对象日志代理器将请求对象httpservletrequest包装成logrequestproxy类型的对象;日志包装过滤器logrequestwrapperfilte通过其自身的返回对象日志代理器将返回对象httpservletresponse包装成logresponseproxy类型的对象;在本实施例中,包装是实现一个同类型的类,该类中有一同类型的属性用于接收原对象,该类只对目标方法进行重写,其它方法则调用原型的方法;日志记录拦截步骤:当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,获取logrequestproxy类型的对象对应的请求参数和请求时间并记录到所述请求对象日志代理器的logmap表中;当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,获取logresponseproxy类型的对象对应的返回值、方法名和当前session信息,并记录到所述返回对象日志代理器的logmap表中;
通过所述日志记录方法,就能从所述对象日志代理器的logmap表中获取到请求参数和请求时间,从所述返回对象日志代理器的logmap表中获取到返回值、方法名和当前session信息,并记录到日志中,如此,得到的日志全面,而不会缺失;日志包装过滤器logrequestwrapperfilter是java web filter接口的实现,其作用是将java web容器所实现的请求对象httpservletrequest和返回对象httpservletresponse分别包装成logrequestproxy类型的对象和logresponseproxy类型的对象并替换之。如图2所示,调用链经过logrequestwrapperfilter前,参数是原始的请求对象httpservletrequest对象和原始的返回对象httpservletresponse,在经过logrequestwrapperfilter后调用链参数替换为logrequestproxy类型的对象和logresponseproxy类型的对象。日志包装过滤器logrequestwrapperfilter在接收httpservletrequest和httpservletresponse的对象后,将它两包装成logrequestproxy类型的对象和logresponseproxy类型的对象然后将logrequestproxy类型的对象替代请求对象httpservletrequest传到续的调用链中,将logresponseproxy类型的对象替代返回对象httpservletresponse传到续的调用链中;请求对象日志代理器和返回对象日志代理器的结构如图3所示,它们都封装了对应的原始象,请求对象日志代理器封装了请求对象httpservletrequest作为原始象,返回对象日志代理器封装了返回对象httpservletresponse作为原始象。这样做的好处是对非目标方法的调用效果和调用原始象的方法是相同的。求对象日志代理器和返回对象日志代理器的内部都设有logmap表。因为logrequestproxy类型的对象和logresponseproxy类型的对象会一直存在于后续的调用参数中,所以当有日志信息需要存放时(尚未到记录日志的时机),可存放在对应的logmap表里;日志记录拦截器loginterceptor作为springmvc拦截器的实现。当调用走到或者返回到拦截器时,springmvc会向日志记录拦截器loginterceptor传相关的调用信息。因此可以在日志记录拦截器loginterceptor实现获取日信息和最终记录日志;一些实施例中,所述日志记录拦截步骤还包括:所述返回对象日志代理器从所述请求对象日志代理器的logmap表中获取请求参数和请求时间,并根据请求时间计算得到调用时间,其中调用时间=当前系统时间-请求时间;然后将返回值、方法名、当前session信息、参数params和调用时间记录到日志中;在本实施例中,计算调用时间中所使用的当前系统时间是当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,获取logresponseproxy类型的对象对应的返回值、方法名和当前session信息,并记录到所述返回对象日志代理器的logmap表中时的时间;值得说明的是,所述日志包装过滤步骤包括:初始化所述请求对象日志代理器,并构造函数接收请求对象;读取请求对象httpservletrequest,并将请求对象httpservletrequest缓存在字节数组中;调用预先重写好的logrequestprox类型的public servletinputstream getinputstream()方法,将缓存在字节数组中的请求对象httpservletrequest重新生成输入流,得到logrequestproxy类型的对象;
请求对象日志代理器在初始化时,构造函数接收请求对象。然后尝试读取请求对象httpservletrequest的输入流。如果读取得到,则将读取到的信息缓存在字节数组中。logrequestprox类型重写了public servletinputstream getinputstream()方法,当调用该方法时,该方法将根据字节数组中的缓存信息重新生成新的输入流。这样就可以重复读取请求体中的参数了;优选的,所述日志包装过滤步骤还包括:当返回对象日志代理器在初始化时,构造函数接收返回对象;重写logresponseproxy类型的public void sendredirect(string location)方法和public printwriter getwriter()方法;在本实施例中,public void sendredirect(string location)方法和public printwriter getwriter()方法为业务调用,现有的所有实现了接口httpservletresponse的类均采用这两个方法;当public void sendredirect(string location)方法被调用时,先将location参数作为请求的返回结果记录到返回对象日志代理器的logmap表中,然后再调用原始返回对象的public void sendredirect(string location)方法;当业务代码调用到public void sendredirect(string location)方法,代表业务逻辑结束并告之调用者重定向;当public printwriter getwriter()方法被调用时,先调用原返回对象的printwriter (),得到输出流对象printwriter后,将输出流对象封装成日志输出流对象logprintwriter;在logprintwriter类型中重写public void write(string s)方法时,先将参数记录到返回对象日志代理器的logmap表中,然后再调用原输出流对象printwriter对象的public void write(string s)方法完成返回。在controller方法中调用response.getwriter()时,实际上获取的是logprintwriter类型的对象。当业务代码调用public printwriter getwriter()方法,代表业务逻辑结束并返回调用者write(string s)参数所传内容。如此,实现业务提前返回;可选的,所述日志记录拦截步骤还包括:当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,通过prehandle方法,先读取url参数和表单参数,并记录到返回对象日志代理器的logmap表中;然后读取请求本参数,并记录到返回对象日志代理器的logmap表中;最后读取记录当前系统时间,将当前系统时间作为请求时间记录到返回对象日志代理器的logmap表中,该当前系统时间为将请求本参数记录到返回对象日志代理器的logmap表中的时间;其中,所述请求参数包括所述url参数、表单参数和请求体参数;public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler)方法中,request此时是logrequestproxy类型的对象,但它也是httpservletrequest类型的对象。所以它可调用的方法和httpservletrequest定义的方法是一致;url参数为:request.getrequesturi();表单参数为: parametermap = request.getparametermap();请求体参数为:先request.getinputstream()得到输入流,再读流里的数据;当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,从prehandle方法的参数request的attributtes和modelandview的modle中获取所有页面模
板参数,从prehandle方法的参数modelandview的view中获取页面模板路径,从参数request中获取路径参数,从参数request中取出当前session信息,从prehandle方法的参数handler中取出对应的方法名,并将当前session信息和方法名记录到所述返回对象日志代理器的logmap表中。public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview)方法中,modelandview就是业务的返回值。prehandle和posthandle是springmvc的拦截器规定的方法。springmvc会在处理流程中传入这些参数;如图4所示,当调用走到日志记录拦截器loginterceptor时,springmvc会传入三个对象:参数request、参数response和参数handler。参数request就是logrequestproxy类型的对象;参数response就是logresponseproxy类型的对象;参数handler是springmvc的handlermethod类型的对象,它包含了controller层处理此次请求的方法的信息。当调用返回到日志记录拦截器loginterceptor时,会比调用时多传一个modelandview对象,是springmvc的modelandview类型的对象,它含有页面模板信息;日志记录拦截器loginterceptor继承springmvc框架所提供的handlerinterceptoradapter类,重写handlerinterceptoradapter类的两个方法:public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler)和public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview);当logrequestproxy类型的对象请求进入日志记录拦截器loginterceptor时,实际进入的是prehandle方法,prehandle方法是进行处理器拦截用的,顾名思义,该方法将在controller处理之前进行调用。此时prehandle方法的参数request实际上已经被志记录拦截器loginterceptor替换成logresponseproxy类型的对象。如此,就可以读取输入流,而不会影响后续业务代码的再次读取输入流。在prehandle方法中,prehandle方法先尝试读取url参数和表单参数,若有则记到返回对象日志代理器的logmap表中:“parameters”:[“name:hello”,”say:world
”……
];然后尝试读取请求本参数,若有则记到返回对象日志代理器的logmap表中:“bodyparameters”:“xxxxx”;然后记录当前时间到返回对象日志代理器的logmap表中:“starttime”:“2022-08-01 08:00:00.000”;当logresponseproxy类型的对象请求经controller层的方法处理后返回到日志记录拦截器loginterceptor时,此时进入的是posthandle方法,posthandle方法的方法参数有四个:参数request、参数response、参数handler和参数modelandview。此时posthandle方法先从参数见request的attributtes和modelandview的modle中获取所有页面模板参数,记为:“modle”:{“user_name”:“xxx”,“user_phone”:“1353453546
”……
}。然后取参数modelandview的view中获取页面模板路径,记为:“view”:“hello/index”。然后尝试从参数request中获取路径参数,有则记为:“pathparameters”:{“id”:xxx,
……
}。然后,再从参数request中取出session,再从参数handler中取出处理请求的方法名。到此所有日志所需要的信息已经完全收集完毕,最后,从返回对象日志代理器的logmap表中,取出logmap表里所有信息,记录日志:{"method": "helloworld.sayhello",
"session": {
……
},"parameters ": ["name:hello","say:world"
……
],"bodyparame":xxxx,"pathparameters":{"id":xxx,
……
},"resutl":{"view":"hello/index","modle":{"user_name":"xxx","user_phone":"1353453546"
……
}},"usedtime":306}具体地,如图6所示,一种日志记录系统,包括请求生成模块、日志包装过滤模块、日志包装过滤模块和日志记录拦截模块;所述请求生成模块用于利用java web容器根据接收到的http请求生成请求对象httpservletrequest和返回对象httpservletresponse;所述日志包装过滤模块用于利用日志包装过滤器logrequestwrapperfilte通过其自身的请求对象日志代理器将请求对象httpservletrequest包装成logrequestproxy类型的对象;用于利用日志包装过滤器logrequestwrapperfilte通过其自身的返回对象日志代理器将返回对象httpservletresponse包装成logresponseproxy类型的对象;所述日志记录拦截模块用于当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,获取logrequestproxy类型的对象对应的请求参数和请求时间并记录到所述请求对象日志代理器的logmap表中;用于当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,获取logresponseproxy类型的对象对应的返回值、方法名和当前session信息,并记录到所述返回对象日志代理器的logmap表中;值得说明的是,所述日志记录拦截模块还用于利用所述返回对象日志代理器从所述请求对象日志代理器的logmap表中获取请求参数和请求时间,并根据请求时间计算得到调用时间,其中调用时间=当前系统时间-请求时间;然后将返回值、方法名、当前session信息、参数params和调用时间记录到日志中;具体地,所述日志包装过滤模块还用于初始化所述请求对象日志代理器,并构造函数接收请求对象;还用于读取请求对象httpservletrequest,并将请求对象httpservletrequest缓存在字节数组中;还用于调用预先重写好的logrequestprox类型的public servletinputstream getinputstream()方法,将缓存在字节数组中的请求对象httpservletrequest重新生成输入流,得到logrequestproxy类型的对象;可选的,所述日志包装过滤模块还用于返回对象日志代理器在初始化时,构造函数接收返回对象;还用于重写logresponseproxy类型的public void sendredirect(string location)方法和public printwriter getwriter()方法;还用于当public void sendredirect(string location)方法被调用时,先将location参数作为请求的返回结果记录到返回对象日志代理器的logmap表中,然后再调用原始返回对象的public void sendredirect(string location)方法;还用于当public printwriter getwriter()方法被调用时,先调用原返回对象的printwriter (),得到输出流对象printwriter后,将输出流对象封装成日志输出流对象
logprintwriter;还用于在logprintwriter类型中重写public void write(string s)方法时,先将参数记录到返回对象日志代理器的logmap表中,然后再调用原输出流对象printwriter对象的public void write(string s)方法完成返回;一些实施例中,所述日志记录拦截模块还用于当logrequestproxy类型的对象进入日志记录拦截器loginterceptor时,通过prehandle方法,先读取url参数和表单参数,并记录到返回对象日志代理器的logmap表中;还用于读取请求本参数,并记录到返回对象日志代理器的logmap表中;还用于读取记录当前系统时间,将当前系统时间作为请求时间记录到返回对象日志代理器的logmap表中;其中,所述请求参数包括所述url参数、表单参数和请求本参数;还用于当logresponseproxy类型的对象进入日志记录拦截器loginterceptor时,从prehandle方法的参数request的attributtes和modelandview的modle中获取所有页面模板参数,从prehandle方法的参数modelandview的view中获取页面模板路径,从参数request中获取路径参数,从参数request中取出当前session信息,从prehandle方法的参数handler中取出对应的方法名,并将当前session信息和方法名记录到所述返回对象日志代理器的logmap表中;以上结合附图对本发明的实施方式作了详细说明,但本发明不限于所描述的实施方式。对于本领域的技术人员而言,在不脱离本发明原理和精神的情况下,对这些实施方式进行多种变化、修改、替换和变型,仍落入本发明的保护范围内。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1