# logback-push-appender
**Repository Path**: zhan_pu/logback-push-appender
## Basic Information
- **Project Name**: logback-push-appender
- **Description**: 此appender可以将您的日志消息推送至阿里钉钉或企业徾信或电子邮箱或自行扩展的任何消息接收渠道。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2022-09-23
- **Last Updated**: 2025-01-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: logback, 告警
## README
# logback-push-appender
当前appender可以将您的日志消息推送至阿里钉钉或企业徾信或电子邮箱或自行扩展的任何消息接收渠道
## 配置
### 添加依赖
```xml
top.v5it
logback-push-appender
0.0.3
ch.qos.logback
logback-classic
1.2.11
cn.hutool
hutool-all
5.7.22
net.logstash.logback
logstash-logback-encoder
5.2
```
### 日志文件配置示例
Check [complete configuration examples](src/example/resources/) for how to configure logback.xml.
### 接收日志渠道
| 接收消息渠道 | 描述 |
|---|---|
| `DingTalkChannelPushStrategy` | 将日志消息推送到阿里钉钉的内部事业群(已支持) |
| `WeiXinChannelPushStrategy` | 将日志消息推送到企业徾信的内部事业群(已支持) |
| `MailChannelPushStrategy` | 将日志消息推送到指定的电子邮箱(已支持) |
| `其他` | 比如短信,需要自己实现`ChannelPushStrategy`接口 |
### 推送日志策略
| 推送日志策略 | 描述 |
|---|---|
| `NotConvergenceStrategy` | 日志到达马上推送 |
| `CountConvergenceStrategy` | 按日志中消息编号`msgId`统计单条日志消息到达数量,当单条日志消息数量达到`limit`限制就推送此条日志消息 |
| `DelayConvergenceStrategy` | 按日志中消息编号`msgId`和当前时间,当单条日志消息到来前后达到`timeout`限制就推送此条日志消息 |
| `FixeTimeCountConvergenceStrategy` | 在固定单位时间`timeout`内按日志中消息编号`msgId`统计单条日志消息到达数量,当单条日志消息数量达到`limit`
限制就推送此条日志消息; 当单条日志消息数量未达到`limit`限制并且超过`timeout`限制,按策略丢弃部分消息等待下个统计周期 |
| `SlidingWindowConvergenceStrategy` | 统计窗口`windowSize`范围内单条日志消息到达数量,当窗口`windowSize`范围内单条日志消息数量到达`limit`限制就推送此条消息 |
### logback-spring.xml
```xml
{
"timestamp":"%date{ISO8601}",
"level": "%level",
"thread":"%thread",
"logger":"%logger",
"message":"#asJson{%message}",
"exception": "%ex"
}
200
2
error.level.color=#dd0000
contacts=zzz****z
atAll=false
server.timeout=60
server.url=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx*************xxxx
WARN
ACCEPT
ERROR
ACCEPT
DENY
```
### 示例说明
```java
package top.v5it.logback.push.convergence;
import cn.hutool.core.lang.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.remoting.RemoteAccessException;
import top.v5it.logback.push.Message;
import top.v5it.logback.push.client.ErrorOutput;
import top.v5it.logback.push.client.ErrorOutputs;
/**
* 示例说明,基于注解方式需要在启动类上添加@EnableErrorOutput,否则注解方式处理无效
*
* @author zhanpu
* @date 2022/9/21
*/
@Slf4j
public class Example {
/**
* 原生方式,自己手动捕获异常处理
*/
public void example_native() {
try {
final Class> clazz = Class.forName("top.v5it.logback.push.convergence.Example");
} catch (ClassNotFoundException e) {
final Message message = new Message()
.setId("notfound_zzz") // 设置消息编号
.setTitle("找不到类") // 设置消息标题
.setDescription("找不到[top.v5it.logback.push.convergence.Example]类");
log.error("{}", message);
}
}
/**
* 基于{@link ErrorOutput}注解方式,适用于用单业务方法
*/
@ErrorOutput(id = "xxxx_1", title = "示例测试")
public void example_annotation() {
boolean biz = false;
Assert.isTrue(biz, "调用业务xx方法失败,可能yy原因");
}
/**
* 基于{@link ErrorOutputs}注解方式,适用在一个方法中包含诸多业务逻辑,并且明确申明所属业务异常
*/
@ErrorOutputs({@ErrorOutput(id = "1234", errorFor = IllegalArgumentException.class), @ErrorOutput(id = "876", errorFor = RemoteAccessException.class)})
public void example_annotation_more() {
boolean biz = false;
Assert.isTrue(biz, "调用业务xx方法失败,可能yy原因");
boolean call_remote = false;
Assert.isTrue(call_remote, () -> new RemoteAccessException("网络超时,调用远程接口失败"));
}
}
```
### TODO