当前位置: 首页 > news >正文

商城网站建设要求网络营销服务

商城网站建设要求,网络营销服务,网站建设哪家好 思创网络,微盟属于营销型手机网站在开发springboot项目时#xff0c;我们可能需要自定义日志实现。需要对slf4j的日志实现进行一次外层包装 这个很简单#xff0c;按照org.slf4j.Logger方式定义一个类Logger类MyLogger。 让后实现MyLoggerImpl#xff1a; public class MyLoggerImpl implements CoreLogge…在开发springboot项目时我们可能需要自定义日志实现。需要对slf4j的日志实现进行一次外层包装 这个很简单按照org.slf4j.Logger方式定义一个类Logger类MyLogger。 让后实现MyLoggerImpl public class MyLoggerImpl implements CoreLogger {private static final String FQCN CoreLoggerImpl.class.getName();private Logger logger null;private Class? clazz;private String className;public CoreLoggerImpl(Logger logger, Class? clazz){this.logger logger;this.clazz clazz;}public CoreLoggerImpl(Logger logger, String clazz){this.logger logger;this.className clazz;}public CoreLoggerImpl(String clazz){this.logger LoggerFactory.getLogger(clazz);this.className clazz;}public CoreLoggerImpl(Class? clazz){this.logger LoggerFactory.getLogger(clazz);this.clazz clazz;}Overridepublic String getName() {return logger.getName();}Overridepublic boolean isTraceEnabled() {return logger.isTraceEnabled();}Overridepublic void trace(String msg) {logger.trace(msg);}/*省略其他的*/Overridepublic void error(Marker marker, String format, Object arg) {logger.error(marker, format, arg);}Overridepublic void error(Marker marker, String format, Object arg1, Object arg2) {logger.error(marker, format, arg1, arg2);}Overridepublic void error(Marker marker, String format, Object... arguments) {logger.error(marker, format, arguments);}Overridepublic void error(Marker marker, String msg, Throwable t) {logger.error(marker, msg, t);} } 然后就可以直接在外部实现获取我么自定义的日志打印了其实这只是对slf4j进行了一次包装。 在使用过程中发现这样的包装方式会导致日志打印出来的行号是错误的行号打印的是MyLoggerImpl的调用行。 在使用slf4j的时候默认引用的是slf4j的org.slf4j.Logger接口这个Logger接口还有一个子接口org.slf4j.spi.LocationAwareLoggerlogback的ch.qos.logback.classic.Logger实现类也实现了这个接口 public interface LocationAwareLogger extends Logger {// these constants should be in EventContants. However, in order to preserve binary backward compatibility// we keep these constants herefinal public int TRACE_INT 00;final public int DEBUG_INT 10;final public int INFO_INT 20;final public int WARN_INT 30;final public int ERROR_INT 40;/*** Printing method with support for location information. * * param marker The marker to be used for this event, may be null.* param fqcn The fully qualified class name of the blogger instance/b,* typically the logger class, logger bridge or a logger wrapper.* param level One of the level integers defined in this interface* param message The message for the log event* param t Throwable associated with the log event, may be null.*/public void log(Marker marker, String fqcn, int level, String message, Object[] argArray, Throwable t);} ch.qos.logback.classic.Logger实现部分 public final class Logger implements org.slf4j.Logger, LocationAwareLogger, AppenderAttachableILoggingEvent, Serializable {public static final String FQCN ch.qos.logback.classic.Logger.class.getName();private void filterAndLog_0_Or3Plus(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params,final Throwable t) {final FilterReply decision loggerContext.getTurboFilterChainDecision_0_3OrMore(marker, this, level, msg, params, t);if (decision FilterReply.NEUTRAL) {if (effectiveLevelInt level.levelInt) {return;}} else if (decision FilterReply.DENY) {return;}buildLoggingEventAndAppend(localFQCN, marker, level, msg, params, t);}public void log(Marker marker, String fqcn, int levelInt, String message, Object[] argArray, Throwable t) {Level level Level.fromLocationAwareLoggerInteger(levelInt);filterAndLog_0_Or3Plus(fqcn, marker, level, message, argArray, t);}public void debug(String msg) {filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, null);} } 通过更深的追踪发现最终决定行号的是以下的代码LineOfCallerConverter  public class LineOfCallerConverter extends ClassicConverter {public String convert(ILoggingEvent le) {StackTraceElement[] cda le.getCallerData();if (cda ! null cda.length 0) {return Integer.toString(cda[0].getLineNumber());} else {return CallerData.NA;}}} ILoggingEvent .getCallerData是获取调用栈信息的。然后去第一个节点(也就是我自定义的类) public class LoggingEvent implements ILoggingEvent {public LoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable, Object[] argArray) {this.fqnOfLoggerClass fqcn;this.loggerName logger.getName();this.loggerContext logger.getLoggerContext();this.loggerContextVO loggerContext.getLoggerContextRemoteView();this.level level;this.message message;this.argumentArray argArray;if (throwable null) {throwable extractThrowableAnRearrangeArguments(argArray);}if (throwable ! null) {this.throwableProxy new ThrowableProxy(throwable);LoggerContext lc logger.getLoggerContext();if (lc.isPackagingDataEnabled()) {this.throwableProxy.calculatePackagingData();}}timeStamp System.currentTimeMillis();}public StackTraceElement[] getCallerData() {if (callerDataArray null) {callerDataArray CallerData.extract(new Throwable(), fqnOfLoggerClass, loggerContext.getMaxCallerDataDepth(), loggerContext.getFrameworkPackages());}return callerDataArray;} } CallerData.extract()方法就是获取slf4j的Logger调用之前的调用栈信息的。public static StackTraceElement[] extract(Throwable t, String fqnOfInvokingClass, final int maxDepth, ListString frameworkPackageList) {if (t null) {return null;}StackTraceElement[] steArray t.getStackTrace();StackTraceElement[] callerDataArray;int found LINE_NA;for (int i 0; i steArray.length; i) {if (isInFrameworkSpace(steArray[i].getClassName(), fqnOfInvokingClass, frameworkPackageList)) {// the caller is assumed to be the next stack frame, hence the 1.found i 1;} else {if (found ! LINE_NA) {break;}}}// we failed to extract caller dataif (found LINE_NA) {return EMPTY_CALLER_DATA_ARRAY;}int availableDepth steArray.length - found;int desiredDepth maxDepth (availableDepth) ? maxDepth : availableDepth;callerDataArray new StackTraceElement[desiredDepth];for (int i 0; i desiredDepth; i) {callerDataArray[i] steArray[found i];}return callerDataArray;} 主要在于 fqnOfLoggerClass, 和 loggerContext.getMaxCallerDataDepth()参数一个日志的调用连的开始处一个是获取的栈深度。fqnOfLoggerClass就是 Logger.log()方法参数中的fqcn 参数。而fqcn就是日志Logger的类名。 所以只要我们控制了fqcn 参数就可以控制日志查找的栈位置进而控制获取的文件以及行号。所以我们需要在我们自定义的日志类中直接调用LocationAwareLogger的log方法并传入我们自己的 fqcn(MyLoggerImpl.class.getName)。 public class MyLoggerImpl implements MyLogger {private static final String FQCN MyLoggerImpl.class.getName();private Logger logger null;private Class? clazz;private String className;public CoreLoggerImpl(Logger logger, Class? clazz){this.logger logger;this.clazz clazz;}public CoreLoggerImpl(Logger logger, String clazz){this.logger logger;this.className clazz;}public CoreLoggerImpl(String clazz){this.logger LoggerFactory.getLogger(clazz);this.className clazz;}public CoreLoggerImpl(Class? clazz){this.logger LoggerFactory.getLogger(clazz);this.clazz clazz;}Overridepublic String getName() {return logger.getName();}/*省略其他的*/Overridepublic void error(Marker marker, String format, Object arg) {// 做判断是以防更改了日志实现框架之后logger未实现LocationAwareLogger接口。如果只是logback使用不需要//(final String localFQCN, final Marker marker, final Level level, final String msg, final Object param, final Throwable t)if (this.logger instanceof LocationAwareLogger) {((LocationAwareLogger) this.logger).log(null, FQCN, LocationAwareLogger.ERROR_INT, msg, null, null);return;}logger.error(marker, format, arg);} }
http://www.dnsts.com.cn/news/243698.html

相关文章:

  • 广州网站改版设计杭州强龙网站建设
  • 免费网站404免费进入响应式布局网站开发
  • 建筑装修设计网站大全seo学院
  • 开发平台需要什么技术网站排名优化公司
  • 公司网站建设哪家正规松岗做网站公司
  • 房产网站建设网站推广徐州经济技术开发区
  • 青海和城乡建设厅网站视频剪辑培训机构哪个好
  • 杭州cms建站模板下载网站kv如何做
  • 高明网站设计公司到底建手机网站还是电脑网站
  • 广东微信网站建设哪家专业淘宝运营培训内容
  • 江苏城乡建设学校网站成都创新网站建设
  • 石家庄网站建设找哪家好哪一个景区网站做的最成熟
  • 网站建设实训的心得的体会桂林象鼻山需要门票吗
  • 巩义做网站优化wordpress 禁用响应式
  • 开发一个网站的步骤流程网站建设合同怎么交印花税
  • 怎么做网站海外运营推广程序员最低学历要求
  • 怎么在网站做gif深圳网站优化哪家好
  • 富锦网站制作phpcms 网站打不开
  • 网站设计制作的服务商免费房屋装修设计
  • 做试卷的网站八桂云网站建设
  • 从零开始网站开发网站设计网页设计公司
  • 电子产品展示网站南山区网站建设
  • 58同城泉州网站建设ps网站设计怎么做
  • 东莞大岭山建网站公司网站建设灬金手指下拉十五
  • 信誉好的品牌网站建设空间商指定的网站目录
  • 大剧院网站建设秦皇岛网站排名
  • 广州站电话怎么自己开公司
  • 北京制作网站公司排名承接婚庆公司网站建设
  • 南宁太阳能网站建设天津滨海新区落户政策
  • 网站开发质量控制计划书邢台市路桥建设总公司网站