就在2026年7月28日的早上也即是刚才群里有很多的告警信息但是我淡定的很因为核心的业务并没有告警。那我就知道可以让团队的人上班后再看了。这就是核心业务都有监控的好处只要核心模块没有告警信息你就可以放心了。因为其他的业务模块有告警不会出大事的顶多是小问题。我这边是在早期就做了一个规定核心模块一定要监控好一出事必须马上知道。而我采用的方式就是一个核心模块一个钉钉监控群。比如订单的一个告警群库存的一个告警群并通过规范化日志打印方便监控。我这边的日志必须是规范化的。因此我提供了一个结构化的日志打印工具代码超级短importcom.alibaba.fastjson2.JSON;importlombok.extern.slf4j.Slf4j;importorg.slf4j.Logger;importjava.util.LinkedHashMap;importjava.util.Map;/** * 结构化日志工具类 * * 使用示例: * // 方式1:传入logger(推荐,类名正确) * StructuredLog.info(log) * .userId(123) * .shopId(456) * .log(); * * // 方式2:不传logger(简便,类名为StructuredLog) * StructuredLog.info() * .userId(123) * .shopId(456) * .log(); * * author linsongbin */Slf4jpublicclassStructuredLog{privatefinalMapString,ObjectfieldsnewLinkedHashMap();privatefinalLogLevellevel;privatefinalLoggerlogger;privateStringmessage;privateThrowablethrowable;privateenumLogLevel{INFO,WARN,ERROR,DEBUG}privateStructuredLog(LogLevellevel,Loggerlogger){this.levellevel;this.loggerlogger;}/** * 创建INFO级别日志(使用调用方logger) */publicstaticStructuredLoginfo(Loggerlogger){returnnewStructuredLog(LogLevel.INFO,logger);}/** * 创建INFO级别日志(使用StructuredLog内置logger) */publicstaticStructuredLoginfo(){returnnewStructuredLog(LogLevel.INFO,log);}/** * 创建WARN级别日志(使用调用方logger) */publicstaticStructuredLogwarn(Loggerlogger){returnnewStructuredLog(LogLevel.WARN,logger);}/** * 创建WARN级别日志(使用StructuredLog内置logger) */publicstaticStructuredLogwarn(){returnnewStructuredLog(LogLevel.WARN,log);}/** * 创建ERROR级别日志(使用调用方logger) */publicstaticStructuredLogerror(Loggerlogger){returnnewStructuredLog(LogLevel.ERROR,logger);}/** * 创建ERROR级别日志(使用StructuredLog内置logger) */publicstaticStructuredLogerror(){returnnewStructuredLog(LogLevel.ERROR,log);}/** * 创建DEBUG级别日志(使用调用方logger) */publicstaticStructuredLogdebug(Loggerlogger){returnnewStructuredLog(LogLevel.DEBUG,logger);}/** * 创建DEBUG级别日志(使用StructuredLog内置logger) */publicstaticStructuredLogdebug(){returnnewStructuredLog(LogLevel.DEBUG,log);}/** * 设置日志消息 */publicStructuredLogmessage(Stringmessage){this.messagemessage;returnthis;}/** * 设置异常信息 */publicStructuredLogexception(Throwablethrowable){this.throwablethrowable;returnthis;}/** * 通用的键值对设置方法 */publicStructuredLogput(Stringkey,Objectvalue){if(key!nullvalue!null){fields.put(key,value);}returnthis;}// 业务字段快捷方法 /** * 用户ID */publicStructuredLoguserId(StringuserId){returnput(userId,userId);}/** * 用户名称 */publicStructuredLoguserName(StringuserName){returnput(userName,userName);}/** * 门店ID */publicStructuredLogshopId(IntegershopId){returnput(shopId,shopId);}/** * 门店名称 */publicStructuredLogshopName(StringshopName){returnput(shopName,shopName);}/** * 单据ID */publicStructuredLogdocsId(LongdocsId){returnput(docsId,docsId);}/** * 单据编号 */publicStructuredLogdocsNo(StringdocsNo){returnput(docsNo,docsNo);}/** * 模块编码 */publicStructuredLogmoduleCode(StringmoduleCode){returnput(moduleCode,moduleCode);}/** * 模块名称 */publicStructuredLogmoduleName(StringmoduleName){returnput(moduleName,moduleName);}/** * 事件编码 */publicStructuredLogeventCode(StringeventCode){returnput(eventCode,eventCode);}/** * 事件名称 */publicStructuredLogeventName(StringeventName){returnput(eventName,eventName);}/** * 业务场景 */publicStructuredLogscenario(Stringscenario){returnput(scenario,scenario);}/** * 状态(如: success/fail/processing) */publicStructuredLogstatus(Stringstatus){returnput(status,status);}/** * 数量(如: 记录数/处理数/失败数) */publicStructuredLogcount(Integercount){returnput(count,count);}/** * 耗时(单位: 毫秒) */publicStructuredLogcostTime(LongcostTime){returnput(costTime,costTime);}/** * 输出日志 */publicvoidlog(){StringlogContentbuildLogContent();switch(level){caseINFO:if(throwable!null){logger.info(logContent,throwable);}else{logger.info(logContent);}break;caseWARN:if(throwable!null){logger.warn(logContent,throwable);}else{logger.warn(logContent);}break;caseERROR:if(throwable!null){logger.error(logContent,throwable);}else{logger.error(logContent);}break;caseDEBUG:if(throwable!null){logger.debug(logContent,throwable);}else{logger.debug(logContent);}break;}}/** * 构建日志内容 */privateStringbuildLogContent(){StringBuildersbnewStringBuilder();if(message!null!message.isEmpty()){sb.append(message).append( || );}// 使用JSON格式输出便于日志平台解析sb.append(JSON.toJSONString(fields));returnsb.toString();}}使用的时候也很简单StructuredLog.error(log).message(门店过时未下单).exception(e).scenario(系统自动下单).moduleCode(order).moduleName(订货单).eventCode(autoCreateOrder).eventName(系统自动下单).shopName(xxx门店).docsNo(docsNo).put(shopId,1).log();这个结构化工具是有模块编码的专门用于监控的。一旦某个关键字模块出现了error日志。我这边对应的钉钉群就会有告警信息。这个日志结构化工具类你可以直接拿去用我已经用了它用了三年了很实用的。在这里我想告诉大家几件事:第一如果你是技术组长/技术经理/技术负责人的一定要做到一件事情核心模块实时监控到位有问题马上处理降低损失否则你可能位置不保第二日志打印一定要结构化不要让团队的人随意乱打第三不要使用一个统一的监控大群而是分模块。也即是一个核心模块一个告警群程序员保护自己从实时监控开始。
2026年7月28日告警信息很多,但我不需理会
就在2026年7月28日的早上也即是刚才群里有很多的告警信息但是我淡定的很因为核心的业务并没有告警。那我就知道可以让团队的人上班后再看了。这就是核心业务都有监控的好处只要核心模块没有告警信息你就可以放心了。因为其他的业务模块有告警不会出大事的顶多是小问题。我这边是在早期就做了一个规定核心模块一定要监控好一出事必须马上知道。而我采用的方式就是一个核心模块一个钉钉监控群。比如订单的一个告警群库存的一个告警群并通过规范化日志打印方便监控。我这边的日志必须是规范化的。因此我提供了一个结构化的日志打印工具代码超级短importcom.alibaba.fastjson2.JSON;importlombok.extern.slf4j.Slf4j;importorg.slf4j.Logger;importjava.util.LinkedHashMap;importjava.util.Map;/** * 结构化日志工具类 * * 使用示例: * // 方式1:传入logger(推荐,类名正确) * StructuredLog.info(log) * .userId(123) * .shopId(456) * .log(); * * // 方式2:不传logger(简便,类名为StructuredLog) * StructuredLog.info() * .userId(123) * .shopId(456) * .log(); * * author linsongbin */Slf4jpublicclassStructuredLog{privatefinalMapString,ObjectfieldsnewLinkedHashMap();privatefinalLogLevellevel;privatefinalLoggerlogger;privateStringmessage;privateThrowablethrowable;privateenumLogLevel{INFO,WARN,ERROR,DEBUG}privateStructuredLog(LogLevellevel,Loggerlogger){this.levellevel;this.loggerlogger;}/** * 创建INFO级别日志(使用调用方logger) */publicstaticStructuredLoginfo(Loggerlogger){returnnewStructuredLog(LogLevel.INFO,logger);}/** * 创建INFO级别日志(使用StructuredLog内置logger) */publicstaticStructuredLoginfo(){returnnewStructuredLog(LogLevel.INFO,log);}/** * 创建WARN级别日志(使用调用方logger) */publicstaticStructuredLogwarn(Loggerlogger){returnnewStructuredLog(LogLevel.WARN,logger);}/** * 创建WARN级别日志(使用StructuredLog内置logger) */publicstaticStructuredLogwarn(){returnnewStructuredLog(LogLevel.WARN,log);}/** * 创建ERROR级别日志(使用调用方logger) */publicstaticStructuredLogerror(Loggerlogger){returnnewStructuredLog(LogLevel.ERROR,logger);}/** * 创建ERROR级别日志(使用StructuredLog内置logger) */publicstaticStructuredLogerror(){returnnewStructuredLog(LogLevel.ERROR,log);}/** * 创建DEBUG级别日志(使用调用方logger) */publicstaticStructuredLogdebug(Loggerlogger){returnnewStructuredLog(LogLevel.DEBUG,logger);}/** * 创建DEBUG级别日志(使用StructuredLog内置logger) */publicstaticStructuredLogdebug(){returnnewStructuredLog(LogLevel.DEBUG,log);}/** * 设置日志消息 */publicStructuredLogmessage(Stringmessage){this.messagemessage;returnthis;}/** * 设置异常信息 */publicStructuredLogexception(Throwablethrowable){this.throwablethrowable;returnthis;}/** * 通用的键值对设置方法 */publicStructuredLogput(Stringkey,Objectvalue){if(key!nullvalue!null){fields.put(key,value);}returnthis;}// 业务字段快捷方法 /** * 用户ID */publicStructuredLoguserId(StringuserId){returnput(userId,userId);}/** * 用户名称 */publicStructuredLoguserName(StringuserName){returnput(userName,userName);}/** * 门店ID */publicStructuredLogshopId(IntegershopId){returnput(shopId,shopId);}/** * 门店名称 */publicStructuredLogshopName(StringshopName){returnput(shopName,shopName);}/** * 单据ID */publicStructuredLogdocsId(LongdocsId){returnput(docsId,docsId);}/** * 单据编号 */publicStructuredLogdocsNo(StringdocsNo){returnput(docsNo,docsNo);}/** * 模块编码 */publicStructuredLogmoduleCode(StringmoduleCode){returnput(moduleCode,moduleCode);}/** * 模块名称 */publicStructuredLogmoduleName(StringmoduleName){returnput(moduleName,moduleName);}/** * 事件编码 */publicStructuredLogeventCode(StringeventCode){returnput(eventCode,eventCode);}/** * 事件名称 */publicStructuredLogeventName(StringeventName){returnput(eventName,eventName);}/** * 业务场景 */publicStructuredLogscenario(Stringscenario){returnput(scenario,scenario);}/** * 状态(如: success/fail/processing) */publicStructuredLogstatus(Stringstatus){returnput(status,status);}/** * 数量(如: 记录数/处理数/失败数) */publicStructuredLogcount(Integercount){returnput(count,count);}/** * 耗时(单位: 毫秒) */publicStructuredLogcostTime(LongcostTime){returnput(costTime,costTime);}/** * 输出日志 */publicvoidlog(){StringlogContentbuildLogContent();switch(level){caseINFO:if(throwable!null){logger.info(logContent,throwable);}else{logger.info(logContent);}break;caseWARN:if(throwable!null){logger.warn(logContent,throwable);}else{logger.warn(logContent);}break;caseERROR:if(throwable!null){logger.error(logContent,throwable);}else{logger.error(logContent);}break;caseDEBUG:if(throwable!null){logger.debug(logContent,throwable);}else{logger.debug(logContent);}break;}}/** * 构建日志内容 */privateStringbuildLogContent(){StringBuildersbnewStringBuilder();if(message!null!message.isEmpty()){sb.append(message).append( || );}// 使用JSON格式输出便于日志平台解析sb.append(JSON.toJSONString(fields));returnsb.toString();}}使用的时候也很简单StructuredLog.error(log).message(门店过时未下单).exception(e).scenario(系统自动下单).moduleCode(order).moduleName(订货单).eventCode(autoCreateOrder).eventName(系统自动下单).shopName(xxx门店).docsNo(docsNo).put(shopId,1).log();这个结构化工具是有模块编码的专门用于监控的。一旦某个关键字模块出现了error日志。我这边对应的钉钉群就会有告警信息。这个日志结构化工具类你可以直接拿去用我已经用了它用了三年了很实用的。在这里我想告诉大家几件事:第一如果你是技术组长/技术经理/技术负责人的一定要做到一件事情核心模块实时监控到位有问题马上处理降低损失否则你可能位置不保第二日志打印一定要结构化不要让团队的人随意乱打第三不要使用一个统一的监控大群而是分模块。也即是一个核心模块一个告警群程序员保护自己从实时监控开始。