You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
411 lines
13 KiB
411 lines
13 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Threading.Tasks;
|
|
|
|
using Aliyun.Acs.Dysmsapi.Model.V20170525;
|
|
using Aliyun.Acs.Core;
|
|
using Aliyun.Acs.Core.Profile;
|
|
|
|
using TencentCloud.Common;
|
|
using TencentCloud.Common.Profile;
|
|
using TencentCloud.Sms.V20190711;
|
|
using TencentCloud.Sms.V20190711.Models;
|
|
|
|
using AliSendSmsRequest = Aliyun.Acs.Dysmsapi.Model.V20170525.SendSmsRequest;
|
|
using AliSendSmsResponse = Aliyun.Acs.Dysmsapi.Model.V20170525.SendSmsResponse;
|
|
|
|
using TxSendSmsRequest = TencentCloud.Sms.V20190711.Models.SendSmsRequest;
|
|
using TxSendSmsResponse = TencentCloud.Sms.V20190711.Models.SendSmsResponse;
|
|
|
|
using System.Net.Http;
|
|
using LitJson;
|
|
using System.Text;
|
|
using System.Net.Http.Headers;
|
|
|
|
namespace Sog
|
|
{
|
|
public class AppAlerter
|
|
{
|
|
private bool USE_TENCENT_CLOUD_SMS = true;
|
|
|
|
private const int DEFAULT_ALERT_INTERVAL = 120;
|
|
ServerApp m_app;
|
|
|
|
string m_serverId;
|
|
string m_smsMsg;
|
|
string m_robotMsg;
|
|
long m_crushUid;
|
|
|
|
object m_locker = new object();
|
|
|
|
Dictionary<string, long> m_lastSendSmsTimeDict = new Dictionary<string, long>();
|
|
Dictionary<string, long> m_lastSendRobotTimeDict = new Dictionary<string, long>();
|
|
|
|
private long m_lastSendRobotTime;
|
|
private int m_sendRobotCount;
|
|
public AppAlerter(ServerApp app)
|
|
{
|
|
m_app = app;
|
|
|
|
m_serverId = ServerIDUtils.IDToString(m_app.ServerID);
|
|
}
|
|
|
|
public void AlertException(Exception ex, long uid = 0)
|
|
{
|
|
lock (m_locker)
|
|
{
|
|
m_crushUid = uid;
|
|
m_smsMsg = "exception: " + ex.Message;
|
|
m_robotMsg = ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace;
|
|
TrySendSms(DEFAULT_ALERT_INTERVAL);
|
|
TrySendRobot(DEFAULT_ALERT_INTERVAL);
|
|
}
|
|
}
|
|
|
|
public void AlertMsg(string msg, int interval = DEFAULT_ALERT_INTERVAL, bool bOnlyRobot = false)
|
|
{
|
|
if(msg == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lock (m_locker)
|
|
{
|
|
m_smsMsg = msg;
|
|
m_robotMsg = msg;
|
|
if (!bOnlyRobot)
|
|
{
|
|
TrySendSms(interval);
|
|
}
|
|
TrySendRobot(interval);
|
|
|
|
}
|
|
}
|
|
|
|
private long GetLastSendSmsTime(string msg)
|
|
{
|
|
if(m_lastSendSmsTimeDict.ContainsKey(msg))
|
|
{
|
|
return m_lastSendSmsTimeDict[msg];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void SetLastSendSmsTime(string msg, long lastTime)
|
|
{
|
|
if (m_lastSendSmsTimeDict.ContainsKey(msg))
|
|
{
|
|
m_lastSendSmsTimeDict[msg] = lastTime;
|
|
}
|
|
else
|
|
{
|
|
m_lastSendSmsTimeDict.Add(msg, lastTime);
|
|
}
|
|
}
|
|
|
|
private long GetLastSendRobotTime(string msg)
|
|
{
|
|
if (m_lastSendRobotTimeDict.ContainsKey(msg))
|
|
{
|
|
return m_lastSendRobotTimeDict[msg];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void SetLastSendRobotTime(string msg, long lastTime)
|
|
{
|
|
if (m_lastSendRobotTimeDict.ContainsKey(msg))
|
|
{
|
|
m_lastSendRobotTimeDict[msg] = lastTime;
|
|
}
|
|
else
|
|
{
|
|
m_lastSendRobotTimeDict.Add(msg, lastTime);
|
|
}
|
|
}
|
|
|
|
private void TrySendSms(int interval)
|
|
{
|
|
if(m_app.AppParam.ServerConfig.alertPhoneNumber == null)
|
|
{
|
|
//TraceLog.Error("AppAlerter.TrySendSms alertPhoneNumber is null");
|
|
return;
|
|
}
|
|
|
|
if (m_app.AppParam.ServerConfig.alertPhoneNumber.Length == 0)
|
|
{
|
|
//TraceLog.Error("AppAlerter.TrySendSms alertPhoneNumber is 0");
|
|
return;
|
|
}
|
|
|
|
long now = m_app.Time.GetTimeSecond();
|
|
long lastTime = GetLastSendSmsTime(m_smsMsg);
|
|
//每种类型的告警1分钟最多发一条短信
|
|
if (now - lastTime < interval)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetLastSendSmsTime(m_smsMsg, now);
|
|
|
|
TraceLog.Error("AppAlerter.TrySendSms new task to send sms msg:{0}", m_smsMsg);
|
|
|
|
Task sendTask = new Task(SendSmsTask);
|
|
sendTask.Start();
|
|
}
|
|
|
|
private void TrySendRobot(int interval)
|
|
{
|
|
if (!m_app.AppParam.ServerConfig.bWechatRobot)
|
|
{
|
|
//TraceLog.Error("AppAlerter.TrySendRobot bWechatRobot is false");
|
|
return;
|
|
}
|
|
|
|
if (String.IsNullOrEmpty(m_app.AppParam.ServerConfig.wechatRobotKey))
|
|
{
|
|
//TraceLog.Error("AppAlerter.TrySendRobot wechatRobotKey is null");
|
|
return;
|
|
}
|
|
|
|
long now = m_app.Time.GetTimeSecond();
|
|
long lastTime = GetLastSendRobotTime(m_robotMsg);
|
|
//每种类型的告警1分钟最多发一条短信
|
|
if (now - lastTime < interval)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetLastSendRobotTime(m_robotMsg, now);
|
|
|
|
if (now - m_lastSendRobotTime > DEFAULT_ALERT_INTERVAL)
|
|
{
|
|
m_lastSendRobotTime = now;
|
|
m_sendRobotCount = 0;
|
|
}
|
|
|
|
if (m_sendRobotCount >= 1) //限制发送次数
|
|
{
|
|
//TraceLog.Error("AppAlerter.TrySendRobot m_sendWechatRobotCount is {0}", m_sendRobotCount);
|
|
return;
|
|
}
|
|
m_sendRobotCount++;
|
|
TraceLog.Trace("AppAlerter.TrySendRobot new task to send WechatRobot msg:{0}", m_robotMsg);
|
|
|
|
Task sendTask = new Task(SendWechatRobotTask);
|
|
sendTask.Start();
|
|
}
|
|
private void SendSmsTask()
|
|
{
|
|
if (USE_TENCENT_CLOUD_SMS)
|
|
{
|
|
SendSmsTaskTencent();
|
|
}
|
|
else
|
|
{
|
|
SendSmsTaskAli();
|
|
}
|
|
}
|
|
|
|
private void SendSmsTaskAli()
|
|
{
|
|
try
|
|
{
|
|
string product = "Dysmsapi";//短信API产品名称
|
|
string domain = "dysmsapi.aliyuncs.com";//短信API产品域名
|
|
string accessId = "LTAIwbt8GxIlFWa0";
|
|
string accessSecret = "qvGEdOJZB60Toq1YMgo5R4QuYTYmQZ";
|
|
string regionIdForPop = "cn-hangzhou";
|
|
|
|
IClientProfile profile = DefaultProfile.GetProfile(regionIdForPop, accessId, accessSecret);
|
|
DefaultProfile.AddEndpoint(regionIdForPop, regionIdForPop, product, domain);
|
|
IAcsClient acsClient = new DefaultAcsClient(profile);
|
|
AliSendSmsRequest request = new AliSendSmsRequest();
|
|
|
|
request.PhoneNumbers = m_app.AppParam.ServerConfig.alertPhoneNumber[0];
|
|
request.SignName = "服务器告警";
|
|
request.TemplateCode = "SMS_25220245";
|
|
string preStr = m_app.AppParam.ServerConfig.alertMsgPre;
|
|
if (preStr == null)
|
|
{
|
|
preStr = "";
|
|
}
|
|
string json = "{\"serverid\":\"" + preStr + m_serverId + m_smsMsg + "\"}";//用于替换短信模板中的变量
|
|
request.TemplateParam = json;
|
|
request.OutId = "xxxxxxxx";
|
|
//请求失败这里会抛ClientException异常
|
|
AliSendSmsResponse sendSmsResponse = acsClient.GetAcsResponse(request);
|
|
if (sendSmsResponse == null)
|
|
{
|
|
TraceLog.Error("AppAlerter.SendSmsTaskAli SendSmsResponse null");
|
|
}
|
|
else
|
|
{
|
|
TraceLog.Error("AppAlerter.SendSmsTaskAli SendSmsResponse code {0}", sendSmsResponse.Code);
|
|
}
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private void SendSmsTaskTencent()
|
|
{
|
|
try
|
|
{
|
|
Credential cred = new Credential
|
|
{
|
|
SecretId = "AKIDjdGdx1MK7vSjkWwmV7oGQJwKTLwioNpo",
|
|
SecretKey = "wc9U0IcgvtazA6nEOfhV3PYPzJH1Yqqb"
|
|
};
|
|
|
|
HttpProfile httpProfile = new HttpProfile();
|
|
httpProfile.Endpoint = ("sms.tencentcloudapi.com");
|
|
|
|
ClientProfile clientProfile = new ClientProfile();
|
|
clientProfile.HttpProfile = httpProfile;
|
|
|
|
TxSendSmsRequest req = new TxSendSmsRequest();
|
|
req.SmsSdkAppid = "1400194039";
|
|
req.Sign = "紫晓互动";
|
|
req.PhoneNumberSet = m_app.AppParam.ServerConfig.alertPhoneNumber;
|
|
// 模板618826, 参数: 机器{1} 进程{2} 发生错误{3}
|
|
req.TemplateID = "618826";
|
|
req.TemplateParamSet = new string[] { GetAlertHostName(), m_serverId, m_smsMsg };
|
|
TraceLog.Trace("AppAlerter.SendSmsTaskTencent app {0} msg {1}", m_serverId, m_smsMsg);
|
|
|
|
SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
|
|
TxSendSmsResponse res = client.SendSmsSync(req);
|
|
|
|
TraceLog.Trace("AppAlerter.SendSmsTaskTencent res {0}", AbstractModel.ToJsonString(res));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Error(e.ToString());
|
|
TraceLog.Exception(e);
|
|
}
|
|
}
|
|
|
|
private string GetAlertHostName()
|
|
{
|
|
string hostname = Dns.GetHostName();
|
|
|
|
//// 后续把hostname修改的直观一些, 就不用这么山寨了
|
|
//if (hostname == "VM-0-10-ubuntu")
|
|
//{
|
|
// return "xjp";
|
|
// //return "119.28.105.46 xjp";
|
|
//}
|
|
|
|
//if (hostname == "VM-0-11-ubuntu")
|
|
//{
|
|
// return "US";
|
|
// //return "150.109.151.80 hk";
|
|
//}
|
|
|
|
//if (hostname == "VM-34-242-ubuntu")
|
|
//{
|
|
// return "guanzhou";
|
|
// //return "111.231.250.180 guanzhou";
|
|
//}
|
|
|
|
////短信有长度限制
|
|
//if (hostname != null && hostname.Length > 11)
|
|
//{
|
|
// hostname = hostname.Substring(0, 11);
|
|
//}
|
|
|
|
return hostname;
|
|
}
|
|
|
|
private void SendWechatRobotTask()
|
|
{
|
|
HttpClient httpClient = null;
|
|
|
|
try
|
|
{
|
|
string key = m_app.AppParam.ServerConfig.wechatRobotKey;
|
|
if(key == null)
|
|
{
|
|
key = "";
|
|
return;
|
|
}
|
|
JsonData jbuilder = new JsonData();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//@人员
|
|
// JsonData mentioned_list = new JsonData();
|
|
// mentioned_list.Add("@all");
|
|
// jtext["mentioned_list"] = mentioned_list;
|
|
|
|
//内容
|
|
string szcontent = $"hostname:{GetAlertHostName()}\nserverid:{m_serverId}msg:{m_robotMsg}";
|
|
if (m_crushUid != 0)
|
|
{
|
|
szcontent = $"hostname:{GetAlertHostName()}\nserverid:{m_serverId}\ncrushuid:{m_crushUid}\nmsg:{m_robotMsg}";
|
|
}
|
|
|
|
string urlHead = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key="; //企业微信
|
|
if (m_app.AppParam.ServerConfig.robotMode == 1) //飞书
|
|
{
|
|
urlHead = "https://open.feishu.cn/open-apis/bot/v2/hook/";
|
|
jbuilder["msg_type"] = "text";
|
|
|
|
JsonData jtext = new JsonData();
|
|
jtext["text"] = szcontent;
|
|
jbuilder["content"] = jtext;
|
|
}
|
|
else
|
|
{
|
|
jbuilder["msgtype"] = "text";
|
|
JsonData jtext = new JsonData();
|
|
jtext["content"] = szcontent;
|
|
jbuilder["text"] = jtext;
|
|
}
|
|
string szContent = jbuilder.ToJson();
|
|
string szurl = $"{urlHead}{key}";
|
|
TraceLog.Debug("http req {0}", szcontent);
|
|
HttpContent content = null;
|
|
string strutf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(szContent));
|
|
content = new StringContent(strutf8);
|
|
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
|
httpClient = new HttpClient();
|
|
httpClient.MaxResponseContentBufferSize = 256000;
|
|
|
|
httpClient.Timeout = TimeSpan.FromSeconds(10);
|
|
|
|
HttpResponseMessage response = httpClient.PostAsync(new Uri(szurl), content).Result;
|
|
if (response != null)
|
|
{
|
|
var result = response.Content.ReadAsStringAsync().Result;
|
|
TraceLog.Trace("AppAlerter.SendWechatRobotTask result {0}", result.ToString());
|
|
}
|
|
else
|
|
{
|
|
TraceLog.Error("AppAlerter.SendWechatRobotTask response is null");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TraceLog.Error("AppAlerter.SendWechatRobotTask ex {0}", ex.ToString());
|
|
}
|
|
finally
|
|
{
|
|
if (httpClient != null)
|
|
{
|
|
httpClient.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|