前言

本章主要介绍Log4j2的几个例子与使用场景。

  • Log4j2 基础样例
  • Log4j2 文件时间&文件大小 Appender设置
  • Log4j2 日志脱敏 (重写Layout实现)
  • Log4j2 日志脱敏 (Layout Replace表达式实现)

本文所用的Demo皆可在我的git项目
https://github.com/SeanYanxml/log4j-demos 内找到。(如果觉得项目写的不错,不妨给我一个star)


Log4j2 Demos


Log4j2 Demos(普通设置)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug"><Appenders><Console name="Console"><PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" /></Console><RollingFile name="RollingAppender" fileName="logs/hello.log" filePattern="logs/hello-{yyyy-MM-dd}-%i.log"><!-- logs/hello-{yyyy-MM-dd HH:mm:ss}-%i.log --><ThresholdFilter level="DEBUG" onMatch="ACCEPT"onMismatch="DENY" /><PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" /><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true" /><SizeBasedTriggeringPolicy size="100KB" /></Policies><DefaultRolloverStrategy max="99999"><Delete basePath="logs" maxDepth="2"><IfFileName glob="hello*.log" /><!-- <IfLastModified age="2m" /> --><IfLastModified age="30d" /></Delete></DefaultRolloverStrategy></RollingFile></Appenders><Loggers><Logger name="com.yanxml" level="DEBUG" additivity="false"><AppenderRef ref="Console" /><AppenderRef ref="RollingAppender" /></Logger><Root level="INFO"><AppenderRef ref="Console" />
<!--            <AppenderRef ref="RollingAppender" />-->        </Root></Loggers></Configuration>
  1. 其中<DefaultRolloverStrategy max="99999">表示目录可以生成的最大文件个数为99999,默认为7.
  2. <delete/>表示删除文件的策略,上述例子表示保留30天数据.
  3. <TimeBasedTriggeringPolicy interval="1" modulate="true" />表示新日志生成间隔时间。
  4. <SizeBasedTriggeringPolicy size="100KB" />表示文件到达多大生成新日志文件或回滚。
#HelloWroldLog4j2
package com.yanxml.log4j2.demos.origin;import org.apache.logging.log4j.LogManager;//import java.util.logging.LogManager;
import org.apache.logging.log4j.Logger;
//import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;/*** The first demo to show the log4j2.* Author Sean* Date 20180529* */public class HelloWroldLog4j2 {public static Logger logger = LogManager.getLogger(HelloWroldLog4j2.class);//  Logger logger = LogManager.getLogger(this.getClass().getName());public static void main(String[] args) {System.out.println("System Out: HelloWorld!");//      logger.trace("Logger Level: TRACE");
//      logger.debug("Logger Level: DEBUG");
//      logger.info("Logger Level: INFO");
//      logger.warn("Logger Level: WARN");logger.error("Error1 , error2, Error3");
//      logger.error("Logger Level: ERROR 123");
//      logger.fatal("Logger Level: FATAL");}}

  • Log4jTimer
package com.yanxml.log4j2.demos.timer;import java.util.TimerTask;import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;public class Log4jTimer extends TimerTask{static Logger logger = LogManager.getLogger(Log4jTimer.class);@Overridepublic void run() {logger.info("Info Log ,Time:"+System.currentTimeMillis()+".");}}
  • Log4jOutTimerDemo
package com.yanxml.log4j2.demos.timer;import java.util.Timer;/*** Set the timer to uptdae the xx.log .* * */
public class Log4jOutTimerDemo {public static void main(String[] args) {Timer timer = new Timer();timer.scheduleAtFixedRate(new Log4jTimer(),1,1);}}
  • log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug"><Appenders><Console name="Console"><PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" /></Console><RollingFile name="RollingAppender" fileName="logs/hello.log" filePattern="logs/hello-%d{yyyy-MM-dd HH:mm:ss}-%i.log"><!-- logs/hello-{yyyy-MM-dd HH:mm:ss}-%i.log --><ThresholdFilter level="DEBUG" onMatch="ACCEPT"onMismatch="DENY" /><PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" /><Policies><!-- interval的单位 与filePattern内的最小参数有关 --><TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!--                <SizeBasedTriggeringPolicy size="1KB" />-->            </Policies><DefaultRolloverStrategy max="99999"><Delete basePath="logs" maxDepth="2"><IfFileName glob="hello*.log" /><!-- <IfLastModified age="2m" /> --><IfLastModified age="30d" /></Delete></DefaultRolloverStrategy></RollingFile></Appenders><Loggers><Logger name="com.yanxml" level="DEBUG" additivity="false"><AppenderRef ref="Console" /><AppenderRef ref="RollingAppender" /></Logger><Root level="INFO"><AppenderRef ref="Console" />
<!--            <AppenderRef ref="RollingAppender" />-->        </Root></Loggers></Configuration>

PS: 日志生成后会每秒生成一个新的日志文件。(interval根据需要进行设置)


Log4j2 Demos(敏感日志设置)

通过查看log4j2的文档,发现Layout支持Replace功能。
需要注意的是
1. 这Replace只支持内容,不支持e(即catch捕获的eroor直接输出).
2. %replace{%msg}{error|ERROR|Error}{Err**} %n就不能再设置为%msg %replace{%msg}{error|ERROR|Error}{Err**} %n,即%msg不能设置两次,否则替换失效。
3. 此法不能涵盖复杂处理的情况。

    <Appenders><Console name="Console"><PatternLayout pattern="%d [%t] %-5p [%c] - %replace{%msg}{error|ERROR|Error}{Err**} %n" /></Console><RollingFile name="RollingAppender" fileName="logs/hello.log" filePattern="logs/hello-{yyyy-MM-dd}-%i.log"><ThresholdFilter level="DEBUG" onMatch="ACCEPT"onMismatch="DENY" /><PatternLayout pattern="%d [%t] %-5p [%c] - %replace{%msg}{error|ERROR|Error}{Err**} %n" /><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true" /><SizeBasedTriggeringPolicy size="100KB" /></Policies><DefaultRolloverStrategy max="99999"><Delete basePath="logs" maxDepth="2"><IfFileName glob="hello*.log" /><!-- <IfLastModified age="2m" /> --><IfLastModified age="30d" /></Delete></DefaultRolloverStrategy></RollingFile></Appenders>

### Log4j2 Demos(敏感日志设置2 自定义Layout)

  • CustomPatternLayout
package com.yanxml.log4j2.demos.sensitive;import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.AbstractStringLayout;
import org.apache.logging.log4j.core.layout.ByteBufferDestination;
import org.apache.logging.log4j.core.layout.Encoder;
import org.apache.logging.log4j.core.layout.PatternSelector;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
import org.apache.logging.log4j.core.pattern.PatternFormatter;
import org.apache.logging.log4j.core.pattern.PatternParser;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
import org.apache.logging.log4j.util.Strings;/*** 定制的输出层,可自由组织要输出的text文本**/
@Plugin(name = "CustomPatternLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
public class CustomPatternLayout extends AbstractStringLayout {/*** 定制输出文本* * @param text* @return*/public static String customize(String text) {return LogUtil.customize(text);}/*** Default pattern string for log output. Currently set to the string* <b>"%m%n"</b> which just prints the application supplied message.*/public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";/*** A conversion pattern equivalent to the TTCCLayout. Current value is <b>%r* [%t] %p %c %notEmpty{%x }- %m%n</b>.*/public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %notEmpty{%x }- %m%n";/*** A simple pattern. Current value is <b>%d [%t] %p %c - %m%n</b>.*/public static final String SIMPLE_CONVERSION_PATTERN = "%d [%t] %p %c - %m%n";/** Key to identify pattern converters. */public static final String KEY = "Converter";/*** Conversion pattern.*/private final String conversionPattern;private final PatternSelector patternSelector;private final Serializer eventSerializer;/*** Constructs a LayoutTest using the supplied conversion pattern.** @param config*            The Configuration.* @param replace*            The regular expression to match.* @param eventPattern*            conversion pattern.* @param patternSelector*            The PatternSelector.* @param charset*            The character set.* @param alwaysWriteExceptions*            Whether or not exceptions should always be handled in this*            pattern (if {@code true}, exceptions will be written even if*            the pattern does not specify so).* @param noConsoleNoAnsi*            If {@code "true"} (default) and {@link System#console()} is*            null, do not output ANSI escape codes* @param headerPattern*            header conversion pattern.* @param footerPattern*            footer conversion pattern.*/private CustomPatternLayout(final Configuration config, final RegexReplacement replace,final String eventPattern, final PatternSelector patternSelector, final Charset charset,final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,final String headerPattern, final String footerPattern) {super(config, charset,createSerializer(config, replace, headerPattern, null, patternSelector,alwaysWriteExceptions, noConsoleNoAnsi),createSerializer(config, replace, footerPattern, null, patternSelector,alwaysWriteExceptions, noConsoleNoAnsi));this.conversionPattern = eventPattern;this.patternSelector = patternSelector;this.eventSerializer = createSerializer(config, replace, eventPattern,DEFAULT_CONVERSION_PATTERN, patternSelector, alwaysWriteExceptions,noConsoleNoAnsi);}public static Serializer createSerializer(final Configuration configuration,final RegexReplacement replace, final String pattern, final String defaultPattern,final PatternSelector patternSelector, final boolean alwaysWriteExceptions,final boolean noConsoleNoAnsi) {if (Strings.isEmpty(pattern) && Strings.isEmpty(defaultPattern)) {return null;}if (patternSelector == null) {try {final PatternParser parser = createPatternParser(configuration);final List<PatternFormatter> list = parser.parse(pattern == null ? defaultPattern : pattern, alwaysWriteExceptions,noConsoleNoAnsi);final PatternFormatter[] formatters = list.toArray(new PatternFormatter[0]);return new PatternSerializer(formatters, replace);} catch (final RuntimeException ex) {throw new IllegalArgumentException("Cannot parse pattern '" + pattern + "'", ex);}}return new PatternSelectorSerializer(patternSelector, replace);}/*** Gets the conversion pattern.** @return the conversion pattern.*/public String getConversionPattern() {return conversionPattern;}/*** Gets this LayoutTest's content format. Specified by:* <ul>* <li>Key: "structured" Value: "false"</li>* <li>Key: "formatType" Value: "conversion" (format uses the keywords* supported by OptionConverter)</li>* <li>Key: "format" Value: provided "conversionPattern" param</li>* </ul>** @return Map of content format keys supporting LayoutTest*/@Overridepublic Map<String, String> getContentFormat() {final Map<String, String> result = new HashMap<>();result.put("structured", "false");result.put("formatType", "conversion");result.put("format", conversionPattern);return result;}/*** Formats a logging event to a writer.** @param event*            logging event to be formatted.* @return The event formatted as a String.*/@Overridepublic String toSerializable(final LogEvent event) {return eventSerializer.toSerializable(event);}@Overridepublic void encode(final LogEvent event, final ByteBufferDestination destination) {if (!(eventSerializer instanceof Serializer2)) {super.encode(event, destination);return;}final StringBuilder text = toText((Serializer2) eventSerializer, event, getStringBuilder());final Encoder<StringBuilder> encoder = getStringBuilderEncoder();encoder.encode(text, destination);trimToMaxSize(text);}/*** Creates a text representation of the specified log event and writes it* into the specified StringBuilder.* <p>* Implementations are free to return a new StringBuilder if they can detect* in advance that the specified StringBuilder is too small.*/private StringBuilder toText(final Serializer2 serializer, final LogEvent event,final StringBuilder destination) {return serializer.toSerializable(event, destination);}/*** Creates a PatternParser.* * @param config*            The Configuration.* @return The PatternParser.*/public static PatternParser createPatternParser(final Configuration config) {if (config == null) {return new PatternParser(config, KEY, LogEventPatternConverter.class);}PatternParser parser = config.getComponent(KEY);if (parser == null) {parser = new PatternParser(config, KEY, LogEventPatternConverter.class);config.addComponent(KEY, parser);parser = config.getComponent(KEY);}return parser;}@Overridepublic String toString() {return patternSelector == null ? conversionPattern : patternSelector.toString();}/*** Creates a pattern layout.** @param pattern*            The pattern. If not specified, defaults to*            DEFAULT_CONVERSION_PATTERN.* @param patternSelector*            Allows different patterns to be used based on some selection*            criteria.* @param config*            The Configuration. Some Converters require access to the*            Interpolator.* @param replace*            A Regex replacement String.* @param charset*            The character set. The platform default is used if not*            specified.* @param alwaysWriteExceptions*            If {@code "true"} (default) exceptions are always written even*            if the pattern contains no exception tokens.* @param noConsoleNoAnsi*            If {@code "true"} (default is false) and*            {@link System#console()} is null, do not output ANSI escape*            codes* @param headerPattern*            The footer to place at the top of the document, once.* @param footerPattern*            The footer to place at the bottom of the document, once.* @return The LayoutTest.*/@PluginFactorypublic static CustomPatternLayout createLayout(@PluginAttribute(value = "pattern", defaultString = DEFAULT_CONVERSION_PATTERN) final String pattern,@PluginElement("PatternSelector") final PatternSelector patternSelector,@PluginConfiguration final Configuration config,@PluginElement("Replace") final RegexReplacement replace,// LOG4J2-783 use platform default by default, so do not specify// defaultString for charset@PluginAttribute(value = "charset") final Charset charset,@PluginAttribute(value = "alwaysWriteExceptions", defaultBoolean = true) final boolean alwaysWriteExceptions,@PluginAttribute(value = "noConsoleNoAnsi", defaultBoolean = false) final boolean noConsoleNoAnsi,@PluginAttribute("header") final String headerPattern,@PluginAttribute("footer") final String footerPattern) {return newBuilder().withPattern(pattern).withPatternSelector(patternSelector).withConfiguration(config).withRegexReplacement(replace).withCharset(charset).withAlwaysWriteExceptions(alwaysWriteExceptions).withNoConsoleNoAnsi(noConsoleNoAnsi).withHeader(headerPattern).withFooter(footerPattern).build();}private static class PatternSerializer implements Serializer, Serializer2 {private final PatternFormatter[] formatters;private final RegexReplacement replace;private PatternSerializer(final PatternFormatter[] formatters,final RegexReplacement replace) {super();this.formatters = formatters;this.replace = replace;}@Overridepublic String toSerializable(final LogEvent event) {final StringBuilder sb = getStringBuilder();try {return toSerializable(event, sb).toString();} finally {trimToMaxSize(sb);}}@Overridepublic StringBuilder toSerializable(final LogEvent event, final StringBuilder buffer) {final int len = formatters.length;for (int i = 0; i < len; i++) {formatters[i].format(event, buffer);}// 对数据进行脱敏处理String strCustomize = customize(buffer.toString());buffer.setLength(0);buffer.append(strCustomize);if (replace != null) { // creates temporary objectsString str = buffer.toString();str = replace.format(str);buffer.setLength(0);buffer.append(str);}return buffer;}@Overridepublic String toString() {final StringBuilder builder = new StringBuilder();builder.append(super.toString());builder.append("[formatters=");builder.append(Arrays.toString(formatters));builder.append(", replace=");builder.append(replace);builder.append("]");return builder.toString();}}private static class PatternSelectorSerializer implements Serializer, Serializer2 {private final PatternSelector patternSelector;private final RegexReplacement replace;private PatternSelectorSerializer(final PatternSelector patternSelector,final RegexReplacement replace) {super();this.patternSelector = patternSelector;this.replace = replace;}public String toSerializable(final LogEvent event) {final StringBuilder sb = getStringBuilder();try {return toSerializable(event, sb).toString();} finally {trimToMaxSize(sb);}}@Overridepublic StringBuilder toSerializable(final LogEvent event, final StringBuilder buffer) {final PatternFormatter[] formatters = patternSelector.getFormatters(event);final int len = formatters.length;for (int i = 0; i < len; i++) {formatters[i].format(event, buffer);}if (replace != null) { // creates temporary objectsString str = buffer.toString();str = replace.format(str);buffer.setLength(0);buffer.append(str);}return buffer;}@Overridepublic String toString() {final StringBuilder builder = new StringBuilder();builder.append(super.toString());builder.append("[patternSelector=");builder.append(patternSelector);builder.append(", replace=");builder.append(replace);builder.append("]");return builder.toString();}}/*** Creates a LayoutTest using the default options. These options include* using UTF-8, the default conversion pattern, exceptions being written,* and with ANSI escape codes.** @return the LayoutTest.* @see #DEFAULT_CONVERSION_PATTERN Default conversion pattern*/public static CustomPatternLayout createDefaultLayout() {return newBuilder().build();}/*** Creates a LayoutTest using the default options and the given* configuration. These options include using UTF-8, the default conversion* pattern, exceptions being written, and with ANSI escape codes.** @param configuration*            The Configuration.** @return the LayoutTest.* @see #DEFAULT_CONVERSION_PATTERN Default conversion pattern*/public static CustomPatternLayout createDefaultLayout(final Configuration configuration) {return newBuilder().withConfiguration(configuration).build();}/*** Creates a builder for a custom LayoutTest.** @return a LayoutTest builder.*/@PluginBuilderFactorypublic static Builder newBuilder() {return new Builder();}/*** Custom LayoutTest builder. Use the* {@link CustomPatternLayout#newBuilder() builder factory method} to create* this.*/public static class Builderimplements org.apache.logging.log4j.core.util.Builder<CustomPatternLayout> {@PluginBuilderAttributeprivate String pattern = CustomPatternLayout.DEFAULT_CONVERSION_PATTERN;@PluginElement("PatternSelector")private PatternSelector patternSelector;@PluginConfigurationprivate Configuration configuration;@PluginElement("Replace")private RegexReplacement regexReplacement;// LOG4J2-783 use platform default by default@PluginBuilderAttributeprivate Charset charset = Charset.defaultCharset();@PluginBuilderAttributeprivate boolean alwaysWriteExceptions = true;@PluginBuilderAttributeprivate boolean noConsoleNoAnsi;@PluginBuilderAttributeprivate String header;@PluginBuilderAttributeprivate String footer;private Builder() {}// TODO: move javadocs from PluginFactory to herepublic Builder withPattern(final String pattern) {this.pattern = pattern;return this;}public Builder withPatternSelector(final PatternSelector patternSelector) {this.patternSelector = patternSelector;return this;}public Builder withConfiguration(final Configuration configuration) {this.configuration = configuration;return this;}public Builder withRegexReplacement(final RegexReplacement regexReplacement) {this.regexReplacement = regexReplacement;return this;}public Builder withCharset(final Charset charset) {// LOG4J2-783 if null, use platform default by defaultif (charset != null) {this.charset = charset;}return this;}public Builder withAlwaysWriteExceptions(final boolean alwaysWriteExceptions) {this.alwaysWriteExceptions = alwaysWriteExceptions;return this;}public Builder withNoConsoleNoAnsi(final boolean noConsoleNoAnsi) {this.noConsoleNoAnsi = noConsoleNoAnsi;return this;}public Builder withHeader(final String header) {this.header = header;return this;}public Builder withFooter(final String footer) {this.footer = footer;return this;}@Overridepublic CustomPatternLayout build() {// fall back to DefaultConfigurationif (configuration == null) {configuration = new DefaultConfiguration();}return new CustomPatternLayout(configuration, regexReplacement, pattern,patternSelector, charset, alwaysWriteExceptions, noConsoleNoAnsi, header,footer);}}
}
  • LogUtil
package com.yanxml.log4j2.demos.sensitive;import lombok.extern.log4j.Log4j2;/**日志工具类* @author dongp**/
@Log4j2
public class LogUtil {private static final String REGEX = "[\\d]{8,15}";private static final String REPLACEMENT = "********";public static void main(String[] args) throws InterruptedException {String text = "asdsad13800005001asd";
//      String text = "asdsad12345678asd";log.info(text);//Thread.sleep(100000);}/*** 定制输出文本 可以根据个人需求进行更改。* * @param text* @return*/public static String customize(String text) {return text.replaceAll(REGEX, REPLACEMENT);}
}//2018-07-27 16:40:14 [main] INFO  LogUtil:com.yanxml.log4j2.demos.sensitive.LogUtil.main(LogUtil.java:17) - asdsad********asd
  • log4j2.xml
<?xml version="1.0" encoding="UTF-8"?><Configuration status="DEBUG" packages="com.yanxml.log4j2.demos.sensitive"><properties><property name="logPath">log</property></properties><Appenders><Console name="Console" target="SYSTEM_OUT"><CustomPatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%l - %msg%n" /></Console><RollingFile name="RollingFile" filename="${logPath}/automation.log"filepattern="${logPath}/%d{yyyyMMddHHmmss}-automation.log"><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" /><Policies><SizeBasedTriggeringPolicy size="100 MB" /></Policies><DefaultRolloverStrategy max="20" /></RollingFile></Appenders><Loggers><Root level="debug"><AppenderRef ref="Console" /><!-- <AppenderRef ref="LogFile" /><AppenderRef ref="RollingFile" /> --><!-- <AppenderRef ref="Rewrite" /> --></Root></Loggers>
</Configuration>

另有更改Log4j2源码包的设置,不推荐。


Reference

[1]. log4j2 java日志脱敏
[2]. 使用log4j2实现日志数据脱敏
[3]. log4j 日志脱敏处理 + java properties文件加载

Log4j2 Demos(基础/时间大小回滚/定期删除/日志脱敏)相关推荐

  1. mysql 回滚删除操作_Mysql如何快速回滚被删除的数据

    在数据库操作中,难免会因为各种各样的原因对数据造成损坏,这个时候就需要对数据库快速恢复.传统的方法会先恢复mysql备份,再去用mysqlbinlog抽取指定时间点的日志,再恢复,这样的操作比较耗时, ...

  2. nginx日志按天生成定期删除日志

    ###nginx日志按天生成&定期删除日志 问题:nginx会按照nginx.conf的配置生成access.log和error.log,随着访问量的增长,日志文件会越来越大,既会影响访问的速 ...

  3. shell脚本 定期删除日志

    定期删除日志: 然后建立清除日志文件的shell脚本,文件名为clean_log 只保留最近三天的日志     #! /bin/bash logdir=/var/log/httpd cd ${logd ...

  4. oracle计算回滚时间,事务回滚时间估算

    事务回滚时间估算 1. 当Oracle处于open 状态,当Oracle回滚事务的时候,可以从used_urec,used_ublk数值可以初步估计Oracle回滚事务 的速度. SQL> se ...

  5. mysql表删除回滚_MySQL删除表的三种方式(小结)

    drop table drop 是直接删除表信息,速度最快,但是无法找回数据 例如删除 user 表: drop table user; truncate (table) truncate 是删除表数 ...

  6. shell 删除七日内日志_SHELL脚本定期删除日志文件(日志定期清理)

    假设我们的应用每天会产生一个日志文件,但我们并没有对日志文件做任何归档处理,久而久之日积月累,就会将磁盘空间占满,从而影响系统的正常运行. 分析磁盘空间占用情况 #当前磁盘空间占用情况 df -h # ...

  7. svn怎么执行清理命令_SHELL脚本定期删除日志文件(日志定期清理)

    假设我们的应用每天会产生一个日志文件,但我们并没有对日志文件做任何归档处理,久而久之日积月累,就会将磁盘空间占满,从而影响系统的正常运行. 分析磁盘空间占用情况 #当前磁盘空间占用情况 df -h # ...

  8. php脚本日志文件,php脚本-定期删除日志文件,删除历史日志 保留最近7天

    最新文章 https: open weixin qq com 有这个的账号,给客户开通微信小程序不需要认证费直... https: open weixin qq com 有这个的账号,给客户开通微信小 ...

  9. mysql 指定回滚_mysql回滚到指定时间点

    # mysql回滚到指定时间点 > 回滚是基于全量备份+增量binlog, 如果binlog没开启, 只能跑路了 场景模拟: > 线上数据库 marketing 在1月5号做了一次全量备份 ...

  10. Kubernetes基础:滚动升级回滚:rolling-update之rollback

    上篇文章介绍了在RC中的滚动升级,这篇继续介绍RC中回滚的方式. RC滚动升级 可参看如下内容:https://liumiaocn.blog.csdn.net/article/details/1042 ...

最新文章

  1. python 正则表达式贪婪模式与非贪婪模式
  2. org.json.JSONException: A JSONObject text must begin with #39;{#39; at character 1 of {解决方法...
  3. [概念型] 区块链包含术语概念【27术语整理汇总】
  4. eclipse安装hadoop插件及配置
  5. 基于ZKWeb + Angular 4.0的开源管理后台Demo
  6. Android系统的开机画面显示过程分析
  7. linux进程状态浅析
  8. MVC利用URLRoute实现伪静态后正真的静态html无法访问
  9. python打印tensor_如何在TensorFlow中打印SparseTensor内容?
  10. 程序猿的键盘侠养成:macOS 常用快捷键分享
  11. 从头开始复习css之选择器(中)
  12. Faster R-CNN算法
  13. 嵌入式开发Linux入门
  14. android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解
  15. 极市直播预告丨阿里达摩院:兼顾速度与精度的高效目标检测框架DAMO-YOLO
  16. 常用小波基函数以及多尺度多分辨率的理解
  17. Spring入门示例
  18. 数据结构 查找 静态查找表算法 折半查找 二叉排序树查找算法 实验报告
  19. 基于值函数逼近的强化学习方法
  20. SSH便利店管理系统

热门文章

  1. 《凤凰架构》读后感 - 演进中的架构
  2. 商标查询工具入口国家知识产权局和阿里云第三方查询工具
  3. SQL分组排序,取每组最新的值
  4. 分式求二阶导数_第12讲 典型例题与练习参考解答:导数的基本运算法则与高阶导数...
  5. matlab的发展历史,仿真的发展历程以及目前现状
  6. 数据挖掘项目---航空公司客户价值分析
  7. 【C语言学习教程---1】VC++6.0的安装和创建简单C语言工程文件教程
  8. Apache Log4j2.x RCE命令执行漏洞攻击原理及修复措施
  9. 雷达原理笔记之LFMCW雷达测距测速原理
  10. php怎么将农历转换成公历,php 公历农历如何实现转换