├── .gitignore ├── LICENSE ├── README.md ├── README.zh-CN.md ├── app.ini ├── control ├── go.mod ├── go.sum ├── logging ├── file.go └── log.go ├── main.go ├── ms-agent.spec └── setting └── setting.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | ms-agent 8 | 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | # vendor/ 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | English | [简体中文](./README.zh-CN.md) 2 | 3 | # ms-agent 4 | 5 | ms-agent is a tool that uses the Go language to write and receive zabbix alarm messages and send them to the [ZbxTable](https://github.com/canghai908/zbxtable) platform. It needs to be used with the ZbxTable platform. 6 | 7 | ## Compile 8 | 9 | ``` bash 10 | mkdir -p $GOPATH/src/github.com/canghai908 11 | cd $GOPATH/src/github.com/canghai908 12 | git clone https://github.com/canghai908/ms-agent.git 13 | cd ms-agent 14 | ./control build 15 | ./control pack 16 | ``` 17 | 18 | ## Releases 19 | V1.0.4 20 | 2022.07.11 21 | 1. Modify the default configuration file to the program directory 22 | 2. The host address of the configuration file does not need to be increased by /v1/receive 23 | 24 | 25 | V1.0.1 26 | 2020.07.24 Fix log log permission issue 27 | 28 | It will compile and generate binary files and package them into a compressed package 29 | 30 | ## Configuration 31 | 32 | The ms-agent deployment needs to be deployed on Zabbix Server. The ms-agent receives zabbix alarm messages and sends them to the ZbxTable platform through the http protocol. Use zbxtable to complete the ms-agent configuration on the zabbix server platform 33 | 34 | ``` 35 | cd /usr/local/zbxtable 36 | ./zbxtable install 37 | ``` 38 | 39 | The display log is as follows 40 | 41 | ``` 42 | 2022/07/04 16:27:48.252 [I] [command.go:163] Create media type successfully! 43 | 2022/07/04 16:27:48.320 [I] [command.go:163] Create user group successfully! 44 | 2022/07/04 16:27:48.575 [I] [command.go:163] Create alarm user successfully! 45 | 2022/07/04 16:27:48.575 [I] [command.go:163] Username : ms-agent 46 | 2022/07/04 16:27:48.575 [I] [command.go:163] Password : qynNlKzMBx 47 | 2022/07/04 16:27:48.668 [I] [command.go:163] Create alarm action successfully! 48 | 2022/07/04 16:27:48.668 [I] [command.go:163] MS-Agent plugin configured successfully! 49 | 2022/07/04 16:27:48.668 [I] [command.go:163] MS-Agent token is de0c0d234f054c74b3d87d715f69afb6 50 | ``` 51 | 52 | This step will create ms-agent on Zabbix Server with random password, configure related actions and media, and associate it with users 53 | 54 | ## Installation 55 | ```` 56 | cd /opt/ 57 | wget https://dl.cactifans.com/zbxtable/ms-agent-1.0.4.tar.gz 58 | tar zxvf ms-agent-1.0.4.tar.gz 59 | mv ms-agent-1.0.4 ms-agent 60 | ```` 61 | 62 | After decompression, a ms-agent binary file and an app.ini configuration file are generated. 63 | 64 | | Program | Function | 65 | | :------- | :-------------------------------------- -------- | 66 | | ms-agent | Receive alerts generated by Zabbix platform and send to ZbxTable platform | 67 | | app.ini | ms-agent configuration file | 68 | 69 | Copy ms-agent to the Alertscripts directory of your zabbix server. The default path is /usr/lib/zabbix/alertscripts/. You can also specify the alertscripts directory by modifying the Zabbix Server configuration file. 70 | Modify the Alertscripts directory of the zabbix server 71 | vi zabbix_server.conf 72 | 73 | ```` 74 | AlertScriptsPath=/usr/lib/zabbix/alertscripts 75 | ```` 76 | 77 | Restart Zabbix Server to take effect. 78 | Copy the ms-agent binary and app.ini configuration file to the alarm script directory configured by the zabbix server 79 | 80 | ```` 81 | cp ms-agent/* /usr/lib/zabbix/alertscripts/ 82 | ```` 83 | 84 | Give the ms-agent script executable permission 85 | 86 | ```` 87 | chmod a+x /usr/lib/zabbix/alertscripts/ms-agent 88 | ```` 89 | 90 | So far the basic installation is complete 91 | 92 | ### config file 93 | The zabbix server will call ms-agent to send alarms, and will also read the app.ini configuration file in the ms-agent program directory. The default content is as follows 94 | 95 | ```` 96 | [app] 97 | Debug = 0 98 | TenantID = zabbix01 99 | LogSavePath = /tmp 100 | Host = http://192.168.10.10:8088 101 | Token = 2d7a7ab0b0be493ab0bb9a925e4a30d2 102 | ```` 103 | 104 | Debug is the program log level 0 is debug, 1 is info 105 | 106 | LogSavePath is the log directory, the default is /tmp directory 107 | 108 | TenantID Tenant id, the default is sufficient. If multiple sets of ms-agent are sent to the same zbxtable, it is recommended to repeat them. 109 | 110 | Host is the access address of the ZbxTable system, the default is http:+ server IP:8088 111 | 112 | Token The Token that communicates with ZbxTable can be modified by itself, and it needs to be consistent with the ZbxTable platform configuration, otherwise the alarm cannot be received. 113 | 114 | ## Debug 115 | 116 | You can modify the configuration file to open the Debug mode, and view the log /tmp/ms-agent_yyyymmdd.log 117 | 118 | ## License 119 | 120 | Apache-2.0 license 121 | 122 | Zbxtable is available under the Apache-2.0 license. See the [LICENSE](LICENSE) file for more info. 123 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 | [English](./README.md) | 简体中文 2 | 3 | # ms-agent 4 | 5 | ms-agent 是一个使用 go 语言编写接收zabbix 的告警消息并发送到 [ZbxTable](https://github.com/canghai908/zbxtable) 平台的工具,需配合 ZbxTable 平台使用。 6 | 7 | ## 编译 8 | 9 | ``` bash 10 | mkdir -p $GOPATH/src/github.com/canghai908 11 | cd $GOPATH/src/github.com/canghai908 12 | git clone https://github.com/canghai908/ms-agent.git 13 | cd ms-agent 14 | ./control build 15 | ./control pack 16 | ``` 17 | 18 | ## 更新记录 19 | V1.0.4 20 | 2022.07.11 21 | 1. 默认配置文件修改为程序目录下 22 | 2. 配置文件host地址不需要增加/v1/receive 23 | 24 | 25 | V1.0.1 26 | 2020.07.24 修复 log 日志权限问题 27 | 28 | 会编译生成二进制文件,并打包到压缩包 29 | 30 | ## 配置 31 | 32 | ms-agent 部署需部署在 Zabbix Server,ms-agent 接收 zabbix 的告警消息,通过 http 协议发送到 ZbxTable 平台,使用 zbxtable 完成 ms-agent 在 zabbix server 平台配置 33 | 34 | ``` 35 | cd /usr/local/zbxtable 36 | ./zbxtable install 37 | ``` 38 | 39 | 显示如下日志 40 | 41 | ``` 42 | 2022/07/04 16:27:48.252 [I] [command.go:163] Create media type successfully! 43 | 2022/07/04 16:27:48.320 [I] [command.go:163] Create user group successfully! 44 | 2022/07/04 16:27:48.575 [I] [command.go:163] Create alarm user successfully! 45 | 2022/07/04 16:27:48.575 [I] [command.go:163] Username : ms-agent 46 | 2022/07/04 16:27:48.575 [I] [command.go:163] Password : qynNlKzMBx 47 | 2022/07/04 16:27:48.668 [I] [command.go:163] Create alarm action successfully! 48 | 2022/07/04 16:27:48.668 [I] [command.go:163] MS-Agent plugin configured successfully! 49 | 2022/07/04 16:27:48.668 [I] [command.go:163] MS-Agent token is de0c0d234f054c74b3d87d715f69afb6 50 | ``` 51 | 52 | 此步骤会在 Zabbix Server 创建 ms-agent,密码为随机,并配置相关 action 和 media,并关联到用户 53 | 54 | ## 安装 55 | 下载二进制文件,并解压 56 | 57 | ``` 58 | cd /opt/ 59 | wget https://dl.cactifans.com/zbxtable/ms-agent-1.0.4.tar.gz 60 | tar zxvf ms-agent-1.0.4.tar.gz 61 | mv ms-agent-1.0.4 ms-agent 62 | ``` 63 | 64 | 解压之后生成一个 ms-agent 二进制文件,一个 app.ini 配置文件。 65 | 66 | | 程序 | 作用 | 67 | | :------- | :----------------------------------------------- | 68 | | ms-agent | 接收 Zabbix 平台产生的告警并发送到 ZbxTable 平台 | 69 | | app.ini | ms-agent 配置文件 | 70 | 71 | 拷贝 ms-agent 到你的 zabbix server 的 Alertscripts 目录下,默认路径为/usr/lib/zabbix/alertscripts/,也可通过修改 Zabbix Server 的配置文件指定alertscripts 目录。 72 | 修改zabbix server的Alertscripts目录 73 | vi zabbix_server.conf 74 | 75 | ``` 76 | AlertScriptsPath=/usr/lib/zabbix/alertscripts 77 | ``` 78 | 79 | 重启 Zabbix Server 生效. 80 | 拷贝ms-agent二进制及app.ini配置文件到zabbix server配置的告警脚本目录 81 | 82 | ``` 83 | cp ms-agent/* /usr/lib/zabbix/alertscripts/ 84 | ``` 85 | 86 | 赋予ms-agent脚本可执行权限 87 | 88 | ``` 89 | chmod a+x /usr/lib/zabbix/alertscripts/ms-agent 90 | ``` 91 | 92 | 至此完成基本安装 93 | 94 | ### 配置文件 95 | zabbix server会调用ms-agent进行告警的发送,同时会读取ms-agent程序目录下的app.ini配置文件,默认内容如下 96 | 97 | ``` 98 | [app] 99 | Debug = 0 100 | TenantID = zabbix01 101 | LogSavePath = /tmp 102 | Host = http://192.168.10.10:8088 103 | Token = 2d7a7ab0b0be493ab0bb9a925e4a30d2 104 | ``` 105 | 106 | Debug 为程序日志级别 0 是 debug,1 为 info 107 | 108 | LogSavePath 为日志目录,默认为/tmp 目录 109 | 110 | TenantID 租户id,默认即可,如有多套ms-agent发送到同一个zbxtable,建议补重复即可 111 | 112 | Host 为 ZbxTable 系统的访问地址,默认为 http:+ 服务器 IP:8088 113 | 114 | Token 与 ZbxTable 通信的 Token,可自行修改,需要与 ZbxTable 平台配置保持一致即可,否则无法接收告警。 115 | 116 | #### Debug 117 | 118 | 可修改配置文件打开 Debug 模式,查看日志文件名格式如下/tmp/ms-agent_yyyymmdd.log 119 | 120 | 121 | ## License 122 | 123 | Apache-2.0 license 124 | 125 | Nightingale is available under the Apache-2.0 license. See the [LICENSE](LICENSE) file for more info. 126 | -------------------------------------------------------------------------------- /app.ini: -------------------------------------------------------------------------------- 1 | [app] 2 | Debug = 1 3 | TenantID = zabbix01 4 | LogSavePath = /tmp 5 | Host = http://192.168.10.10:8088 6 | Token = ec573cf7388da56916f75ba9bbe46a69 -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # release version 4 | version=1.0.4 5 | 6 | CWD=$(cd $(dirname $0)/; pwd) 7 | cd $CWD 8 | 9 | usage() 10 | { 11 | echo $"Usage: $0 {build|pack} " 12 | exit 0 13 | } 14 | 15 | build() 16 | { 17 | export GO111MODULE=on 18 | export CGO_ENABLED=0 19 | export GOPROXY=https://goproxy.cn 20 | go build -a -v -ldflags "-X main.version=${version} -X main.buildTime=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.gitHash=`git rev-parse HEAD`" -o ms-agent main.go 21 | } 22 | 23 | pack() 24 | { 25 | mkdir -p ms-agent-${version} 26 | mv ms-agent app.ini ms-agent-${version}/ 27 | tar zcvf ms-agent-${version}.tar.gz ms-agent-${version}/ 28 | } 29 | 30 | case "$1" in 31 | build) 32 | build $2 33 | ;; 34 | pack) 35 | pack $2 36 | ;; 37 | *) 38 | usage 39 | esac -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/canghai908/ms-agent 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/go-ini/ini v1.55.0 7 | github.com/sirupsen/logrus v1.6.0 8 | github.com/smartystreets/goconvey v1.7.2 // indirect 9 | gopkg.in/ini.v1 v1.66.6 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/go-ini/ini v1.55.0 h1:0wVcG9udk2C3TGgmdIGKK9ScOZHZB5nbG+gwji9fhhc= 4 | github.com/go-ini/ini v1.55.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 5 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 6 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 7 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 8 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 9 | github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= 10 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 11 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 12 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 13 | github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= 14 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 15 | github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= 16 | github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= 17 | github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= 18 | github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= 19 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= 20 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 21 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 22 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 23 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 24 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= 25 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 26 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 27 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 28 | gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= 29 | gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 30 | -------------------------------------------------------------------------------- /logging/file.go: -------------------------------------------------------------------------------- 1 | package logging 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "mime/multipart" 7 | "os" 8 | "path" 9 | "time" 10 | 11 | "github.com/canghai908/ms-agent/setting" 12 | ) 13 | 14 | //getLogFilePath func 15 | func getLogFilePath() string { 16 | return fmt.Sprintf("%s", setting.AppSetting.LogSavePath) 17 | } 18 | 19 | //getLogFileName a 20 | func getLogFileName() string { 21 | return fmt.Sprintf("%s%s.%s", 22 | "ms-agent_", 23 | time.Now().Format("20060102"), 24 | "log", 25 | ) 26 | } 27 | 28 | //GetSize a 29 | func GetSize(f multipart.File) (int, error) { 30 | content, err := ioutil.ReadAll(f) 31 | 32 | return len(content), err 33 | } 34 | 35 | //GetExt a 36 | func GetExt(fileName string) string { 37 | return path.Ext(fileName) 38 | } 39 | 40 | //CheckNotExist a 41 | func CheckNotExist(src string) bool { 42 | _, err := os.Stat(src) 43 | 44 | return os.IsNotExist(err) 45 | } 46 | 47 | //CheckPermission a 48 | func CheckPermission(src string) bool { 49 | _, err := os.Stat(src) 50 | 51 | return os.IsPermission(err) 52 | } 53 | 54 | //IsNotExistMkDir a 55 | func IsNotExistMkDir(src string) error { 56 | if notExist := CheckNotExist(src); notExist == true { 57 | if err := MkDir(src); err != nil { 58 | return err 59 | } 60 | } 61 | 62 | return nil 63 | } 64 | 65 | //MkDir a 66 | func MkDir(src string) error { 67 | err := os.MkdirAll(src, 0755) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | return nil 73 | } 74 | 75 | //Open a 76 | func Open(name string, flag int, perm os.FileMode) (*os.File, error) { 77 | f, err := os.OpenFile(name, flag, perm) 78 | if err != nil { 79 | return nil, err 80 | } 81 | 82 | return f, nil 83 | } 84 | 85 | //MustOpen a 86 | func MustOpen(fileName, filePath string) (*os.File, error) { 87 | 88 | src := filePath + "/" 89 | perm := CheckPermission(src) 90 | if perm == true { 91 | return nil, fmt.Errorf("file.CheckPermission Permission denied src: %s", src) 92 | } 93 | 94 | err := IsNotExistMkDir(src) 95 | if err != nil { 96 | return nil, fmt.Errorf("file.IsNotExistMkDir src: %s, err: %v", src, err) 97 | } 98 | 99 | f, err := Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0755) 100 | if err != nil { 101 | return nil, fmt.Errorf("Fail to OpenFile :%v", err) 102 | } 103 | 104 | return f, nil 105 | } 106 | -------------------------------------------------------------------------------- /logging/log.go: -------------------------------------------------------------------------------- 1 | package logging 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | //Level a 12 | type Level int 13 | 14 | var ( 15 | //F as 16 | F *os.File 17 | //DefaultPrefix s 18 | DefaultPrefix = "" 19 | //DefaultCallerDepth a 20 | DefaultCallerDepth = 2 21 | //logger ss 22 | logger *log.Logger 23 | //logPrefix s 24 | logPrefix = "" 25 | //levelFlags aa 26 | levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"} 27 | ) 28 | 29 | const ( 30 | //DEBUG a 31 | DEBUG Level = iota 32 | //INFO a 33 | INFO 34 | //WARNING a 35 | WARNING 36 | //ERROR a 37 | ERROR 38 | //FATAL a 39 | FATAL 40 | ) 41 | 42 | //Setup setup 43 | func Setup() { 44 | var err error 45 | filePath := getLogFilePath() 46 | fileName := getLogFileName() 47 | F, err = MustOpen(fileName, filePath) 48 | if err != nil { 49 | log.Fatalf("logging.Setup err: %v", err) 50 | return 51 | } 52 | logger = log.New(F, DefaultPrefix, log.LstdFlags) 53 | } 54 | 55 | //Debug a 56 | func Debug(v ...interface{}) { 57 | setPrefix(DEBUG) 58 | logger.Println(v) 59 | 60 | } 61 | 62 | //Info a 63 | func Info(v ...interface{}) { 64 | setPrefix(INFO) 65 | logger.Println(v) 66 | } 67 | 68 | //Warn a 69 | func Warn(v ...interface{}) { 70 | setPrefix(WARNING) 71 | logger.Println(v) 72 | } 73 | 74 | //Error as 75 | func Error(v ...interface{}) { 76 | setPrefix(ERROR) 77 | logger.Println(v) 78 | } 79 | 80 | //Fatal ldevel 81 | func Fatal(v ...interface{}) { 82 | setPrefix(FATAL) 83 | logger.Fatalln(v) 84 | } 85 | 86 | //setPrefix a 87 | func setPrefix(level Level) { 88 | _, file, line, ok := runtime.Caller(DefaultCallerDepth) 89 | if ok { 90 | logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line) 91 | } else { 92 | logPrefix = fmt.Sprintf("[%s]", levelFlags[level]) 93 | } 94 | logger.SetPrefix(logPrefix) 95 | } 96 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "os" 10 | "time" 11 | 12 | "github.com/canghai908/ms-agent/logging" 13 | "github.com/canghai908/ms-agent/setting" 14 | ) 15 | 16 | //AppVersion version 17 | var ( 18 | vers *bool 19 | help *bool 20 | 21 | version = "No Version Provided" 22 | gitHash = "No GitHash Provided" 23 | buildTime = "No BuildTime Provided" 24 | ) 25 | 26 | func init() { 27 | vers = flag.Bool("v", false, "display the version.") 28 | help = flag.Bool("h", false, "print this help.") 29 | flag.Parse() 30 | 31 | if *vers { 32 | fmt.Println("Version:", version) 33 | fmt.Println("Git Commit Hash:", gitHash) 34 | fmt.Println("UTC Build Time:", buildTime) 35 | os.Exit(0) 36 | } 37 | 38 | if *help { 39 | flag.Usage() 40 | os.Exit(0) 41 | } 42 | 43 | setting.Setup() 44 | logging.Setup() 45 | } 46 | 47 | func main() { 48 | if len(os.Args) < 3 { 49 | logging.Error("parameter missing") 50 | return 51 | } 52 | if setting.AppSetting.Debug == "0" { 53 | logging.Debug("os.Args[1]:", os.Args[1]) 54 | logging.Debug("os.Args[2]:", os.Args[2]) 55 | logging.Debug("os.Args[3]:", os.Args[3]) 56 | } 57 | post := []byte(os.Args[3]) 58 | client := &http.Client{ 59 | Timeout: 5 * time.Second, 60 | } 61 | addr := setting.AppSetting.Host + "/v1/receive" 62 | req, err := http.NewRequest("POST", addr, bytes.NewReader(post)) 63 | if err != nil { 64 | logging.Error(err) 65 | return 66 | } 67 | if setting.AppSetting.Debug == "0" { 68 | logging.Debug("Send --->>>", string(post)) 69 | } 70 | token := setting.AppSetting.Token 71 | req.Header.Add("Token", token) 72 | req.Header.Add("ZBX-TenantID", setting.AppSetting.TenantID) 73 | req.Header.Add("User-Agent", "Zabbix-Client") 74 | resp, err := client.Do(req) 75 | if err != nil { 76 | logging.Error(err) 77 | return 78 | } 79 | defer resp.Body.Close() 80 | b, err := ioutil.ReadAll(resp.Body) 81 | if err != nil { 82 | logging.Error(err) 83 | return 84 | } 85 | if setting.AppSetting.Debug == "0" { 86 | logging.Debug("Receive <<<---", string(b)) 87 | } 88 | logging.Info("send ok!") 89 | } 90 | -------------------------------------------------------------------------------- /ms-agent.spec: -------------------------------------------------------------------------------- 1 | Name: ms-agent 2 | Version: %{version} 3 | Release: 1%{?alphatag:.%{alphatag}}%{?dist} 4 | Summary: A tools send zabbix alerts to ZbxTable 5 | Group: Applications/Internet 6 | License: Apache-2.0 7 | URL: https://zbxtable.cactifans.com 8 | Source0: ms-agent-%{version}%{?alphatag:%{alphatag}}.tar.gz 9 | 10 | Buildroot: %{_tmppath}/ms-agent-%{version}-%{release}-root-%(%{__id_u} -n) 11 | 12 | %description 13 | A tools send zabbix alerts to ZbxTable 14 | 15 | %global debug_package %{nil} 16 | 17 | %prep 18 | %setup0 -q -n ms-agent-%{version}%{?alphatag:%{alphatag}} 19 | 20 | %build 21 | 22 | %install 23 | 24 | rm -rf $RPM_BUILD_ROOT 25 | 26 | # install necessary directories 27 | mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/ms-agent 28 | mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zabbix/alertscripts 29 | 30 | # install binaries and conf 31 | install -m 0755 -p ms-agent $RPM_BUILD_ROOT%{_prefix}/lib/zabbix/alertscripts/ 32 | install -m 0755 -p app.ini $RPM_BUILD_ROOT%{_sysconfdir}/ms-agent/ 33 | 34 | exit 0 35 | 36 | %clean 37 | rm -rf $RPM_BUILD_ROOT 38 | 39 | 40 | %define __debug_install_post \ 41 | %{_rpmconfigdir}/find-debuginfo.sh %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ 42 | %{nil} 43 | 44 | %files 45 | %defattr(755,root,root,755) 46 | %dir %{_prefix}/lib/zabbix/alertscripts/ 47 | %dir %{_sysconfdir}/ms-agent/ 48 | %{_prefix}/lib/zabbix/alertscripts/ms-agent 49 | %{_sysconfdir}/ms-agent/app.ini 50 | -------------------------------------------------------------------------------- /setting/setting.go: -------------------------------------------------------------------------------- 1 | package setting 2 | 3 | import ( 4 | "github.com/go-ini/ini" 5 | log "github.com/sirupsen/logrus" 6 | "os" 7 | "path" 8 | ) 9 | 10 | var cfg *ini.File 11 | 12 | type App struct { 13 | Debug string 14 | TenantID string 15 | LogSavePath string 16 | Host string 17 | Token string 18 | } 19 | 20 | var AppSetting = &App{} 21 | 22 | func Setup() { 23 | Mpath, err := os.Executable() 24 | if err != nil { 25 | log.Errorln(err) 26 | } 27 | cfg, err = ini.Load(path.Dir(Mpath) + "/app.ini") 28 | if err != nil { 29 | log.Errorln("Fail to parse 'app.ini': %v", err) 30 | return 31 | } 32 | mapTo("app", AppSetting) 33 | } 34 | 35 | func mapTo(section string, v interface{}) { 36 | err := cfg.Section(section).MapTo(v) 37 | if err != nil { 38 | log.Errorln("Cfg.MapTo RedisSetting err: %v", err) 39 | return 40 | } 41 | } 42 | --------------------------------------------------------------------------------