-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
45 changed files
with
6,848 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ | |
|
||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 | ||
.glide/ | ||
.idear |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,80 @@ | ||
# supervisor-listener | ||
# supervisor-event-listener | ||
Supervisor事件通知, 支持邮件, Slack, WebHook | ||
|
||
## 简介 | ||
Supervisor是*nix环境下的进程管理工具, 可以把前台进程转换为守护进程, 当进程异常退出时自动重启. | ||
supervisor-event-listener监听进程异常退出事件, 并发送通知. | ||
|
||
## 下载 | ||
* [Linux-64位](http://opns468ov.bkt.clouddn.com/supervisor/supervisor-event-listener-linux-amd64.tar.gz) | ||
* [Mac OS-64位](http://opns468ov.bkt.clouddn.com/supervisor/supervisor-event-listener-darwin-amd64.tar.gz) | ||
|
||
### 源码安装 | ||
* `go get -u github.com/ouqiang/supervisor-event-listener` | ||
|
||
## Supervisor配置 | ||
```ini | ||
[eventlistener:supervisor-event-listener] | ||
; 默认读取配置文件/etc/supervisor-event-listener.ini | ||
command=/path/to/supervisor-event-listener | ||
; 指定配置文件路径 | ||
;command=/path/to/supervisor-event-listener -c /path/to/supervisor-event-listener.ini | ||
events=PROCESS_STATE_EXITED | ||
...... | ||
``` | ||
|
||
## 配置文件, 默认读取`/etc/supervisor-event-listener.ini` | ||
|
||
```ini | ||
[default] | ||
# 通知类型 mail,slack,webhook 只能选择一种 | ||
notify_type = mail | ||
|
||
# 邮件服务器配置 | ||
mail.server.user = [email protected] | ||
mail.server.password = 123456 | ||
mail.server.host = smtp.163.com | ||
mail.server.port = 25 | ||
|
||
# 邮件收件人配置, 多个收件人, 逗号分隔 | ||
mail.user = [email protected] | ||
|
||
# Slack配置 | ||
slack.webhook_url = https://hooks.slack.com/services/xxxx/xxx/xxxx | ||
slack.channel = exception | ||
|
||
# WebHook通知URL配置 | ||
webhook_url = http://my.webhook.com | ||
|
||
``` | ||
|
||
## 通知内容 | ||
邮件、Slack | ||
```shell | ||
Host: ip(hostname) | ||
Process: process-name | ||
PID: 6152 | ||
EXITED FROM state: RUNNING | ||
``` | ||
WebHook, Post请求, 字段含义查看Supervisor文档 | ||
```json | ||
{ | ||
"Header": { | ||
"Ver": "3.0", | ||
"Server": "supervisor", | ||
"Serial": 11, | ||
"Pool": "supervisor-listener", | ||
"PoolSerial": 11, | ||
"EventName": "PROCESS_STATE_EXITED", | ||
"Len": 84 | ||
}, | ||
"Payload": { | ||
"Ip": "ip(hostname)", | ||
"ProcessName": "process-name", | ||
"GroupName": "group-name", | ||
"FromState": "RUNNING", | ||
"Expected": 0, | ||
"Pid": 6371 | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#!/usr/bin/env bash | ||
|
||
# set -x -u | ||
# 构建应用, supervisor-event-listener.tar.gz | ||
# ./build.sh -p linux -a amd64 | ||
# 参数含义 | ||
# -p 指定平台(linux|darwin) | ||
# -a 指定体系架构(amd64|386), 默认amd64 | ||
|
||
|
||
TEMP_DIR=`date +%s`-temp-`echo $RANDOM` | ||
|
||
# 目标平台 linux,darwin | ||
OS='' | ||
# 目标平台架构 | ||
ARCH='' | ||
# 应用名称 | ||
APP_NAME='supervisor-event-listener' | ||
# 可执行文件名 | ||
EXEC_NAME='' | ||
# 压缩包名称 | ||
COMPRESS_FILE='' | ||
|
||
|
||
# -p 平台 -a 架构 | ||
while getopts "p:a:" OPT; | ||
do | ||
case $OPT in | ||
p) OS=$OPTARG | ||
;; | ||
a) ARCH=$OPTARG | ||
;; | ||
esac | ||
done | ||
|
||
if [[ -z $OS ]];then | ||
echo "平台不能为空" | ||
exit 1 | ||
fi | ||
|
||
if [[ $OS && $OS != 'linux' && $OS != 'darwin' ]];then | ||
echo '平台错误,支持的平台 linux darmin(osx)' | ||
exit 1 | ||
fi | ||
|
||
if [[ -z $ARCH ]];then | ||
ARCH='amd64' | ||
fi | ||
|
||
if [[ $ARCH != '386' && $ARCH != 'amd64' ]];then | ||
echo 'arch错误,仅支持 386 amd64' | ||
exit 1 | ||
fi | ||
|
||
echo '开始编译' | ||
|
||
GOOS=$OS GOARCH=$ARCH go build -ldflags '-w' | ||
|
||
if [[ $? != 0 ]];then | ||
exit 1 | ||
fi | ||
echo '编译完成' | ||
|
||
|
||
EXEC_NAME=${APP_NAME} | ||
COMPRESS_FILE=${APP_NAME}-${OS}-${ARCH}.tar.gz | ||
|
||
mkdir -p $TEMP_DIR/$APP_NAME | ||
if [[ $? != 0 ]]; then | ||
exit 1 | ||
fi | ||
|
||
# 需要打包的文件 | ||
PACKAGE_FILENAME=(supervisor-event-listener.ini ${EXEC_NAME}) | ||
|
||
echo '复制文件到临时目录' | ||
# 复制文件到临时目录 | ||
for i in ${PACKAGE_FILENAME[*]} | ||
do | ||
cp -r $i $TEMP_DIR/$APP_NAME | ||
done | ||
|
||
|
||
echo '压缩文件' | ||
# 压缩文件 | ||
cd $TEMP_DIR | ||
|
||
tar czf $COMPRESS_FILE * | ||
mv $COMPRESS_FILE ../ | ||
cd ../ | ||
|
||
rm $EXEC_NAME | ||
rm -rf $TEMP_DIR | ||
|
||
echo '打包完成' | ||
echo '生成压缩文件--' $COMPRESS_FILE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package config | ||
|
||
import ( | ||
"flag" | ||
"strings" | ||
"fmt" | ||
"os" | ||
"gopkg.in/ini.v1" | ||
"github.com/ouqiang/supervisor-event-listener/utils" | ||
) | ||
|
||
type Config struct { | ||
NotifyType string | ||
WebHook WebHook | ||
MailServer MailServer | ||
MailUser MailUser | ||
Slack Slack | ||
} | ||
|
||
type WebHook struct { | ||
Url string | ||
} | ||
|
||
type Slack struct { | ||
WebHookUrl string | ||
Channel string | ||
} | ||
|
||
// 邮件服务器 | ||
type MailServer struct { | ||
User string | ||
Password string | ||
Host string | ||
Port int | ||
} | ||
|
||
// 接收邮件的用户 | ||
type MailUser struct { | ||
Email []string | ||
} | ||
|
||
func ParseConfig() *Config { | ||
var configFile string | ||
flag.StringVar(&configFile, "c", "/etc/supervisor-event-listener.ini", "config file") | ||
flag.Parse() | ||
configFile = strings.TrimSpace(configFile) | ||
if configFile == "" { | ||
Exit("请指定配置文件路径") | ||
} | ||
file, err := ini.Load(configFile) | ||
if err != nil { | ||
Exit("读取配置文件失败#" + err.Error()) | ||
} | ||
section := file.Section("default") | ||
notifyType := section.Key("notify_type").String() | ||
notifyType = strings.TrimSpace(notifyType) | ||
if !utils.InStringSlice([]string{"mail", "slack", "webhook"}, notifyType) { | ||
Exit("不支持的通知类型-" + notifyType) | ||
} | ||
|
||
config := &Config{} | ||
config.NotifyType = notifyType | ||
switch notifyType { | ||
case "mail": | ||
config.MailServer = parseMailServer(section) | ||
config.MailUser = parseMailUser(section) | ||
case "slack": | ||
config.Slack = parseSlack(section) | ||
case "webhook": | ||
config.WebHook = parseWebHook(section) | ||
} | ||
|
||
return config | ||
} | ||
|
||
func parseMailServer(section *ini.Section) MailServer { | ||
user := section.Key("mail.server.user").String() | ||
user = strings.TrimSpace(user) | ||
password := section.Key("mail.server.password").String() | ||
password = strings.TrimSpace(password) | ||
host := section.Key("mail.server.host").String() | ||
host = strings.TrimSpace(host) | ||
port, portErr := section.Key("mail.server.port").Int() | ||
if user == "" || password == "" || host == "" || portErr != nil { | ||
Exit("邮件服务器配置错误") | ||
} | ||
|
||
mailServer := MailServer{} | ||
mailServer.User = user | ||
mailServer.Password = password | ||
mailServer.Host = host | ||
mailServer.Port = port | ||
|
||
return mailServer | ||
} | ||
|
||
func parseMailUser(section *ini.Section) MailUser { | ||
user := section.Key("mail.user").String() | ||
user = strings.TrimSpace(user) | ||
if user == "" { | ||
Exit("邮件收件人配置错误") | ||
} | ||
mailUser := MailUser{} | ||
mailUser.Email = strings.Split(user, ",") | ||
|
||
return mailUser | ||
} | ||
|
||
|
||
func parseSlack(section *ini.Section) Slack { | ||
webHookUrl := section.Key("slack.webhook_url").String() | ||
webHookUrl = strings.TrimSpace(webHookUrl) | ||
channel := section.Key("slack.channel").String() | ||
channel = strings.TrimSpace(channel) | ||
if webHookUrl == "" || channel == "" { | ||
Exit("Slack配置错误") | ||
} | ||
|
||
slack := Slack{} | ||
slack.WebHookUrl = webHookUrl | ||
slack.Channel = channel | ||
|
||
return slack | ||
} | ||
|
||
func parseWebHook(section *ini.Section) WebHook { | ||
url := section.Key("webhook_url").String() | ||
url = strings.TrimSpace(url) | ||
if url == "" { | ||
Exit("WebHookUrl配置错误") | ||
} | ||
webHook := WebHook{} | ||
webHook.Url = url | ||
|
||
|
||
return webHook | ||
} | ||
|
||
func Exit(msg string) { | ||
fmt.Fprintln(os.Stderr, msg) | ||
os.Exit(1) | ||
} |
Oops, something went wrong.