Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

Logback学习笔记

8
Mar
2018

Logback学习笔记

By Alex
/ in Java
/ tags LOG
0 Comments
简介

Logback的目标是作为Log4j的继任者。Logback使用模块化的架构,主要分为三个部分:logback-core、logback-classic、logback-access。

模块logback-classic作为Log4j的继任者,它做了根本性的改进。该模块实现了SLF4J API,你可以方便的切换到其它日志框架。模块logback-access和Servlet容器集成,提供HTTP访问日志的功能。在logback-core的基础上,你可以方便的轻易的构建自己的模块。

Logback比起Log4j的优势包括:

  1. 在某些关键的执行路径上,提供高于Log4j十倍的性能,同时具有比Log4j更低的内存占用
  2. logback-classic直接实现了SLF4J API,而Log4J需要经过适配才能使用SLF4J
  3. 支持XML和Groovy两种配置风格
  4. 在配置文件修改后,实时的重新加载,不需要重启应用
  5. 优雅的重IO错误中恢复:FileAppender及其子类(例如RollingFileAppender)能在文件服务器宕机恢复后,自动重连,不需要重启应用
  6. 自动移除旧日志归档,你可以设置TimeBasedRollingPolicy、SizeAndTimeBasedFNATP的maxHistory属性,以控制日志文件的数量
  7. 自动压缩日志归档文件,RollingFileAppender 能够在Rollover时自动、异步的压缩日志文件
  8. Prudent Mode:支持多个JVM中运行的FileAppender安全的向同一个文件进行写入
  9. 配置文件的条件式处理,你可以在配置文件中添加 <if>等元素
  10. 过滤器,Logback提供比Log4j更加强大的过滤器机制
  11. SiftingAppender,可以基于任何运行时属性来分离日志。例如,根据用户会话来分割日志,每个会话产生一个日志文件
  12. 异常栈增强 —— 支持软件包信息,例如 struts-1.2.9.jar:1.2.9
Maven依赖
XML
1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
自动化配置

你可以通过编程,或者指定配置文件,来配置Logback。默认配置行为如下:

  1. 尝试寻找类路径下的 logback-test.xml
  2. 如果找不到,尝试寻找logback.groovy
  3. 如果找不到,尝试寻找logback.xml 
  4. 尝试寻找类路径下META-INF/services/ch.qos.logback.classic.spi.Configurator指定的配置类,获得的全限定名称用于配置Logback
  5. 如果以上步骤都失败,使用 BasicConfigurator,直接打印到控制台

注意,配置文件位置可以通过系统属性 -Dlogback.configurationFile=/path/to/config.xml指定。

配置文件说明
configuration

这是根配置元素:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--
    debug设置为true,打印Logback状态信息
    scan设置为true,自动扫描配置文件的修改,并重新载入
    scanPeriod 默认每分钟扫描一次,如果不指定单位,则单位ms
    packagingData="true" 在栈信息中附加包信息,1.1.4以后默认禁用
-->
<configuration debug="true" scan="true" scanPeriod="30 seconds" packagingData="true">
    <!-- 设置LoggerContext名称 -->
    <contextName>logbacktesst</contextName>
 
    <!-- 定义属性 -->
    <property name="USER_HOME" value="/home/alex"/>
    <!-- 从JNDI获取属性 -->
    <insertFromJNDI env-entry-name="java:comp/env/userhome" as="USER_HOME"/>
    <!-- 将当前时间定义为属性-->
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
 
    <!-- 下面的子元素单独阐述 -->
    <include />
    <if />
    <appender />
    <logger />
</configuration>
include

用于包含其它文件中的配置信息:

XML
1
<include file="http://dev.gmem.cc/logback/basic.xml"/>

被包含的文件,格式必须如下:

XML
1
2
3
4
<!-- 必须以include为根元素 -->
<included>
    <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender" />
</included>
if

用于条件化配置:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<if condition='property("HOSTNAME").contains("zircon")'>
    <then>
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d %-5level %logger{35} - %msg %n</pattern>
            </encoder>
        </appender>
        <root>
            <appender-ref ref="STDOUT"/>
        </root>
    </then>
    <else>
    </else>
</if>
logger
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 根日志器 -->
<root level="debug"> <!-- 设置为OFF则关闭根日志器 -->
    <!-- 每个日志器都可以引用多个Appender -->
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="FILE"/>
</root>
<!-- 自定义日志器,以及其最低级别-->
<logger name="cc.gmem" level="INFO"/>
<!-- 默认情况下,每个日志器会调用自己的Appender,也会使用所有祖先的Appender -->
<!-- 设置additivity为false,则不使用任何祖先Appender -->
<logger name="cc.gmem.study.logback.LogbackTest" level="DEBUG" additivity="false">
    <appender-ref ref="FILE"/>
</logger>
appender 

定义日志追加器,负责把LogEvent输出到目的地。

ConsoleAppender
XML
1
2
3
4
5
6
7
8
9
10
<!-- 输出到控制台的Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
    <!-- 也可以输出到System.err -->
    <target>System.out</target>
    <!-- 设置为true则可以在Windows下支持彩色输出,需要依赖org.fusesource.jansi:jansi:1.9 -->
    <withJansi>false</withJansi>
</appender>
FileAppender
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 输出到文件的Appender -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <!-- 可以引用定义的属性,进行变量替换 -->
    <file>${USER_HOME}logbacktest.log</file>
    <!-- 唯一性文件名  -->
    <file>log-${bySecond}.txt</file>
    <encoder>
        <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
    <!-- 默认true,是否附加到文件的尾部,设置为false则文件的原有内容被清除 -->
    <append>true</append>
    <!-- 默认true,设置为false可以大大提升日志吞吐量,但是程序崩溃可能丢失日志 -->
    <immediateFlush>false</immediateFlush>
    <!-- 如果设置为true则日志被安全的写入文件,即使存在其它JVM的FileAppender在使用此文件 -->
    <prudent>false</prudent>
</appender>
RollingFileAppender
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!-- 滚动文件Appender -->
<appender name="RFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <!--
        滚动策略,基于时间滚动
    -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--
            文件名模式:
            %d{yyyy-MM-dd-HH, UTC}
            %d{yyyy-MM-dd}
        -->
        <!-- 每日滚动出一个文件-->
        <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
        <!-- 最多保留的日志文件数量,老的日志自动移除 -->
        <!-- 保留30天的日志历史 -->
        <maxHistory>30</maxHistory>
        <!-- 日志占用空间限制,如果超过限制,从最老的文件开始删除,删除是异步的 -->
        <!-- 最多占用3GB -->
        <totalSizeCap>3GB</totalSizeCap>
        <!-- 如果设置为true,则在启动时移除归档日志 -->
        <cleanHistoryOnStart>false</cleanHistoryOnStart>
    </rollingPolicy>
    <!--
        滚动策略,基于时间 + 尺寸
    -->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- 每日滚定,%i为文件计数,初始值0 -->
        <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
        <!-- 单个文件最多100MB,保留60天历史,最大占用空间20GB -->
        <maxFileSize>100MB</maxFileSize>
        <maxHistory>60</maxHistory>
        <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <!-- 触发策略:负责确定何时执行rollover -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <!-- 如果当前文件超过5MB,则触发Appender进行是否需要rollover的判断 -->
        <maxFileSize>5MB</maxFileSize>
    </triggeringPolicy>
    <encoder>
        <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender>
SocketAppender
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 连接到远程日志服务器,推送日志 -->
<!-- 通过套接字发送日志 -->
<appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
    <remoteHost>${host}</remoteHost>
    <port>${port}</port>
    <reconnectionDelay>10000</reconnectionDelay>
    <includeCallerData>${includeCallerData}</includeCallerData>
</appender>
<!-- 通过SSL发送日志 -->
<appender name="SOCKETSSL" class="ch.qos.logback.classic.net.SSLSocketAppender">
    <remoteHost>${host}</remoteHost>
    <port>${port}</port>
    <reconnectionDelay>10000</reconnectionDelay>
    <ssl>
        <trustStore>
            <location>${truststore}</location>
            <password>${password}</password>
        </trustStore>
    </ssl>
</appender>
ServerSocketAppender
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 创建一个日志服务器并监听,向所有连接到此服务器的客户端推送日志 -->
<!-- 在客户端连接之前产生的日志,简单的丢弃 -->
<appender name="SERVER" class="ch.qos.logback.classic.net.server.ServerSocketAppender">
    <port>${port}</port>
    <includeCallerData>${includeCallerData}</includeCallerData>
</appender>
<appender name="SERVERSSL" class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
    <port>${port}</port>
    <includeCallerData>${includeCallerData}</includeCallerData>
    <ssl>
        <keyStore>
            <location>${keystore}</location>
            <password>${password}</password>
        </keyStore>
    </ssl>
</appender>
DBAppender 
XML
1
2
3
4
5
6
7
8
9
<!-- 将日志记录到数据库 -->
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
        <driverClass>com.mysql.jdbc.Driver</driverClass>
        <url>jdbc:mysql://host_name:3306/datebase_name</url>
        <user>username</user>
        <password>password</password>
    </connectionSource>
</appender>
SyslogAppender
XML
1
2
3
4
5
6
<!-- 写到Syslog中 -->
<appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
    <syslogHost>remote_home</syslogHost>
    <facility>AUTH</facility>
    <suffixPattern>[%thread] %logger %msg</suffixPattern>
</appender>
SiftingAppender
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 根据特定的运行时属性,对日志文件进行分割 -->
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
    <!-- 根据运行时属性userid进行分割 -->
    <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
        <key>userid</key>
        <defaultValue>unknown</defaultValue>
    </discriminator>
    <sift>
        <appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
            <!-- 运行时属性可以随意引用 -->
            <file>${userid}.log</file>
            <append>false</append>
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
            </layout>
        </appender>
    </sift>
</appender>

配合此Appender的Java代码:

Java
1
2
3
4
logger.debug("Application started");
// 设置运行时属性
MDC.put("userid", "Alice");
logger.debug("Alice says hello");
AsyncAppender

此日志追加器能够异步的记录ILoggingEvent,它本身仅仅作为事件分发器,必须引用其它Appender负责实际的日志记录。

AsyncAppender在BlockingQueue中对日志进行缓冲,它会创建一个专门的工作线程,从队列的头部获取日志,并分发给单个子Appender。默认情况下,队列用量超过80%后,AsyncAppender会丢弃TRACE, DEBUG,INFO级别的日志信息。

队列的默认容量为256,如果队列满了,调用logger.***的应用程序线程会阻塞。

你必须在关闭JVM进程之前,明确的关闭AsyncAppender,以防止日志事件丢失(未来得及分发)。你可以显式调用:

Java
1
2
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.stop();

或者使用Java的ShutdownHook:

XML
1
2
3
<configuration debug="true">
   <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook" />
</configuration>

AsyncAppender配置示例:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 队列容量 -->
    <queueSize>256</queueSize>
    <!-- 仅剩多少容量时,开始丢弃不重要的日志,设置为0则不丢弃 -->
    <discardingThreshold>20</discardingThreshold>
    <!-- 当LoggerContext停止时,AsyncAppender.stop()等待多长时间,让日志被刷出到appender-ref -->
    <maxFlushTime>1000</maxFlushTime>
    <!-- 如果设置为true,队列满了会直接丢弃信息,而不是阻塞 -->
    <neverBlock>false</neverBlock>
 
    <!-- 实际负责日志记录的Appender -->
    <appender-ref ref="FILE" />
</appender>
Layout

此接口负责格式化日志事件:

Java
1
2
3
4
5
6
7
8
public interface Layout<E> extends ContextAware, LifeCycle {
    String doLayout(E event);
    String getFileHeader();
    String getPresentationHeader();
    String getFileFooter();
    String getPresentationFooter();
    String getContentType();
}

你可以注册自己实现的Layout:

XML
1
2
3
4
5
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="cc.gmem.study.logback.JsonLayout" />
    </encoder>
</appender>
PatternLayout

这是一个灵活的Layout,通过一个字符串指定输出格式。

转换符 说明
c{length}
lo{length}
logger{length}

原始日志事件的Logger名称

1
2
3
4
5
6
7
8
9
10
11
12
13
%logger      mainPackage.sub.sample.Bar   mainPackage.sub.sample.Bar
 
%logger{0}   mainPackage.sub.sample.Bar   Bar
 
%logger{5}   mainPackage.sub.sample.Bar   m.s.s.Bar
 
%logger{10}  mainPackage.sub.sample.Bar   m.s.s.Bar
 
%logger{15}  mainPackage.sub.sample.Bar   m.s.sample.Bar
 
%logger{16}  mainPackage.sub.sample.Bar   m.sub.sample.Bar
 
%logger{26}  mainPackage.sub.sample.Bar   mainPackage.sub.sample.Bar
C{length}
class{length}
调用日志的代码所属类的全限定名称 
contextName
cn
LoggerContext的名称
d{pattern}
date{pattern}
d{pattern, timezone}
date{pattern, timezone}
日志事件的名称:
1
2
3
4
5
6
7
8
9
%d                                2006-10-20 14:06:49,812
 
%date                             2006-10-20 14:06:49,812
 
%date{ISO8601}                    2006-10-20 14:06:49,812
 
%date{HH:mm:ss.SSS}               14:06:49.812
 
%date{dd MMM yyyy;HH:mm:ss.SSS}   20 oct. 2006;14:06:49.812
F / file 调用日志的代码的Java源文件名称
caller{depth}  调用日志的代码的位置信息
L / line 调用日志的代码的行号
m / msg / message 日志内容
M / method 调用日志的代码所在的方法
n 依赖于平台的换行符
p / le / level 日志级别
r / relative 从JVM启动到日志发生时,流逝的毫秒数
t / thread 产生日志事件的线程名
X{key:-defaultVal}
mdc{key:-defaultVal}
产生日志线程关联的关联MDC(mapped diagnostic context)中的值
ex{depth}
exception{depth}
throwable{depth}
输出关联到日志事件的调用栈信息
xEx{depth}
xException{depth}
xThrowable{depth}
类似上面,外加包信息

 格式化修饰符,下面是一些修是%logger的例子:

修饰符 说明
%20logger 如果宽度不足20,左侧补空白
%-20logger 如果宽度不足20,右侧补空白
%.30logger 如果宽度超过30,从左侧截断
%.-30logger 如果宽度超过30,从右侧截断
%20.30logger 如果宽度不足20,左侧补空白;如果宽度超过30,从左侧截断

支持颜色代码:%black", "%red", "%green","%yellow","%blue", "%magenta","%cyan", "%white", "%gray", "%boldRed","%boldGreen", "%boldYellow", "%boldBlue", "%boldMagenta""%boldCyan", "%boldWhite" 和 "%highlight" 。

Pattern示例:

1
2
3
4
[%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n
# 输出
[main] WARN  c.l.TrivialMain - a warning message 0
[main] DEBUG c.l.TrivialMain - hello world number1
logback-access扩展

ch.qos.logback.access.PatternLayout扩展了以下转换符:

转换符 说明
a / remoteIP 远程IP地址
A / localIP 本地IP地址
b / B / bytesSent 响应长度
h / clientHost 远程主机名
H / protocol 请求协议
reqParameter{paramName} 输出指定请求参数
reqAttribute{attributeName} 输出指定的请求属性
i{header} / header{header} 输出指定请求头
responseHeader{header} 输出指定响应头
reqCookie{cookie} 输出指定Cookie值
m / requestMethod 请求的HTTP方法
r / requestURL 请求URL
s / statusCode 状态码
D / elapsedTime 处理请求消耗的时间,单位毫秒
T / elapsedSeconds 处理请求消耗的时间,单位秒
t / date 输出时间,例如%t{dd MMM yyyy ;HH:mm:ss,SSS}
u / user 输出远程用户
q / queryString 输出查询字符串,包括前缀?
U / requestURI 请求的URI
S / sessionID SessionID
v / server 服务器名称
I / threadName 处理请求的线程名称
localPort 本地端口
encoder

编码器,负责将日志事件转换为字节数组,并写入到输出流。

logstash-logback-encoder

JSON格式编码器,用于配合Logstash,示例:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <!-- 对输出的JSON进行格式化 -->
        <jsonGeneratorDecorator class="net.logstash.logback.decorate.PrettyPrintingJsonGeneratorDecorator"/>
        <!-- 时间输出为UNIX时间戳 -->
        <timestampPattern>[UNIX_TIMESTAMP_AS_NUMBER]</timestampPattern>
        <!-- 对字段进行重命名 -->
        <fieldNames>
            <timestamp>instant</timestamp>
            <logger>loggerName</logger>
            <thread>thread</thread>
            <stackTrace>thrown</stackTrace>
            <!-- 丢弃字段 -->
            <version>[ignore]</version>
            <levelValue>[ignore]</levelValue>
        </fieldNames>
    </encoder>
    <target>System.out</target>
</appender> 
log-access
配合Tomcat

当前版本可以和JDK7 + Tomcat 7.0.62配合使用:

  1. 将logback-access.jar与logback-core.jar复制到$TOMCAT_HOME/lib/目录下 
  2. 修改配置文件:
    $TOMCAT_HOME/conf/server.xml
    XML
    1
    2
    3
    <!-- 添加在Engine或Host元素内部 -->
    <!-- quiet进制打印默认的状态信息 -->
    <ValveclassName="ch.qos.logback.access.tomcat.LogbackValve" quiet="true" filename="logback-access.xml"/> 
  3. logback默认会在$TOMCAT_HOME/conf下查找配置文件logback-access.xml,配置示例:

    logback-access.xml
    XML
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <configuration>
      <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />  
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>%h %l %u %user %date "%r" %s %b</pattern>
        </encoder>
      </appender>
      <appender-ref ref="STDOUT" />
    </configuration>

重启Tomcat即可。

← 使用Eclipse Memory Analyzer分析JVM堆Dump
InfluxDB学习笔记 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • Log4J2学习笔记
  • 使用log4jdbc记录SQL语句的执行情况
  • log4j配置文件样本
  • 基于EFK构建日志分析系统
  • C++日志组件spdlog

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2