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

网站流量统计怎么做的电子工程类

网站流量统计怎么做的,电子工程类,媒体平台,网站采集到wordpress在开发springboot项目时,我们可能需要自定义日志实现。需要对slf4j的日志实现进行一次外层包装 这个很简单,按照org.slf4j.Logger方式定义一个类Logger类MyLogger。 让后实现MyLoggerImpl: 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.LocationAwareLogger,logback的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 <b>logger 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, AppenderAttachable<ILoggingEvent>, 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, List<String> 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.yayakq.cn/news/593487/

相关文章:

  • 惠州网站公司舞蹈东莞网站建设
  • 手机网站开源系统wordpress热门文章插件
  • 软文范文大全1000字合肥企业网站seo
  • 淮南 搭建一个企业展示网站aws个人免费版
  • 莱芜雪野湖天气预报windows优化大师的优点
  • 手机网站建设模板免费网站模板网
  • 永兴集团网站营销网站价格
  • 折叠网站开发工程师游戏开发引擎
  • 原型设计网站英文手表网站
  • 网站提示404error网站流量太高 如何做负载均衡
  • 苏州网站建设选苏州梦易行深圳推广系统多少钱
  • 大型网站开发技术网站优化软件方案
  • 借贷网站建设网络营销的主要特点有哪些
  • 东莞做创意网站seo企业优化方案
  • 网站建设实战案例廊坊网站建设策划
  • 儿童网站建设外文翻译腾讯邮箱企业邮箱入口网址
  • 福田网站建设有限公司中企高呈建设网站
  • 课程网站设计建设显示网站正在建设中
  • 使用网站的mysql东莞产品网站建设公司
  • 怎么增加网站浏览量seoul是啥意思
  • 免费做外贸的网站平台网站改版的几个建议
  • 河池网站优化wordpress 文章商品
  • 免费网站设计 优帮云求佛山公共频道电视直播网址
  • 凡科建站教程南京模板建网站哪家好
  • 海珠做网站公司广州定制网站建设方案书
  • 郑州响应式建站上海网站托管
  • 维护一个网站雄安 网站建设
  • 贵阳网站建设贵阳网站建设哪家好网络公司企业网站源码
  • 湖南营销类网站设计长沙市旅游景点
  • 中英文网站栏目修改网站绩效营销