Revision | 97 (tree) |
---|---|
Zeit | 2019-02-22 20:54:49 |
Autor | ![]() |
Teams通知アクションを追加
@@ -0,0 +1,129 @@ | ||
1 | +/* | |
2 | + * EventWatch | |
3 | + * Copyright(C) 2019 BananaJinn. | |
4 | + */ | |
5 | +using System; | |
6 | +using System.IO; | |
7 | +using System.Net; | |
8 | +using System.Text; | |
9 | +using System.Web; | |
10 | +using EWatch.Models; | |
11 | +using EWatch.Utils; | |
12 | +using Newtonsoft.Json.Linq; | |
13 | + | |
14 | +namespace EWatch.Actions | |
15 | +{ | |
16 | + /// <summary> | |
17 | + /// MS Teams に通知するアクションです。 | |
18 | + /// </summary> | |
19 | + public class ActionTeams : BaseAction | |
20 | + { | |
21 | + public const string Name = "teams"; | |
22 | + | |
23 | + | |
24 | + /// <summary> | |
25 | + /// URL | |
26 | + /// </summary> | |
27 | + public string URL { get; set; } | |
28 | + /// <summary> | |
29 | + /// テーマカラー | |
30 | + /// </summary> | |
31 | + public string ThemeColor { get; set; } | |
32 | + | |
33 | + public ActionTeams() | |
34 | + { | |
35 | + } | |
36 | + | |
37 | + public override bool Validate() | |
38 | + { | |
39 | + if (Util.IsNullOrEmpty(URL)) { | |
40 | + log.Error("URL is not specified."); | |
41 | + return false; | |
42 | + } | |
43 | + return true; | |
44 | + } | |
45 | + | |
46 | + public override void Execute(LogData data) | |
47 | + { | |
48 | + var json = GetJSON(data); | |
49 | + //Send(HttpUtility.UrlEncode(json)); | |
50 | + Send(json); | |
51 | + } | |
52 | + | |
53 | + private string GetSubject(string value) | |
54 | + { | |
55 | + if (!string.IsNullOrEmpty(value)) { | |
56 | + // 改行があればそこで区切る | |
57 | + var array = value.Split('\n'); | |
58 | + value = array[0]; | |
59 | + // 255文字以上ならそこで区切る | |
60 | + if (value.Length > 255) | |
61 | + value = value.Substring(0, 255); | |
62 | + } | |
63 | + return value; | |
64 | + } | |
65 | + | |
66 | + private string GetJSON(LogData data) | |
67 | + { | |
68 | + var jo = new JObject(); | |
69 | + jo["@type"] = "MessageCard"; | |
70 | + if (!Util.IsNullOrEmpty(ThemeColor)) { | |
71 | + jo["themeColor"] = ThemeColor; | |
72 | + } | |
73 | + jo["summary"] = string.Format("notification from {0}", data.HostName); | |
74 | + jo["title"] = string.Format("[{0}] {1}", data.HostName, GetSubject(data.Message)); | |
75 | + jo["sections"] = new JArray(GetSection(data)); | |
76 | + return jo.ToString(); | |
77 | + } | |
78 | + | |
79 | + private object GetSection(LogData data) | |
80 | + { | |
81 | + dynamic result = new JObject(); | |
82 | + result.facts = new JArray( | |
83 | + GetFact("Time", data.TimeStamp.Value.ToString("yyyy-MM-dd HH:mm:ss.fff")), | |
84 | + GetFact("Level", data.Level), | |
85 | + GetFact("Code", data.Code.ToString()), | |
86 | + GetFact("Host", data.HostName), | |
87 | + GetFact("Source", data.Source) | |
88 | + ); | |
89 | + result.text = data.Message; | |
90 | + return result; | |
91 | + } | |
92 | + | |
93 | + private object GetFact(string name, string value) | |
94 | + { | |
95 | + dynamic result = new JObject(); | |
96 | + result.name = name; | |
97 | + result.value = value; | |
98 | + return result; | |
99 | + } | |
100 | + | |
101 | + private string Send(string postData) | |
102 | + { | |
103 | + var data = Encoding.UTF8.GetBytes(postData); | |
104 | + var req = (HttpWebRequest)WebRequest.Create(URL); | |
105 | + req.Method = "POST"; | |
106 | + req.ContentType = "application/x-www-form-urlencoded"; | |
107 | + req.ContentLength = data.Length; | |
108 | + | |
109 | + using (Stream s = req.GetRequestStream()) { | |
110 | + s.Write(data, 0, data.Length); | |
111 | + } | |
112 | + | |
113 | + try { | |
114 | + string result = null; | |
115 | + WebResponse res = req.GetResponse(); | |
116 | + using (var sr = new StreamReader(res.GetResponseStream())) { | |
117 | + result = sr.ReadToEnd(); | |
118 | + } | |
119 | + return result; | |
120 | + } catch (WebException e) { | |
121 | + string responseText = null; | |
122 | + using (var r = new StreamReader(e.Response.GetResponseStream())) { | |
123 | + responseText = r.ReadToEnd(); | |
124 | + } | |
125 | + throw new Exception(string.Concat("Request Error:", responseText), e); | |
126 | + } | |
127 | + } | |
128 | + } | |
129 | +} |
@@ -28,6 +28,6 @@ | ||
28 | 28 | // |
29 | 29 | // You can specify all the values or you can use the default the Revision and |
30 | 30 | // Build Numbers by using the '*' as shown below: |
31 | -[assembly: AssemblyVersion("1.0.27")] | |
31 | +[assembly: AssemblyVersion("1.0.28")] | |
32 | 32 | |
33 | 33 | //[assembly: log4net.Config.XmlConfigurator(ConfigFile=@"Log4net.Config.xml", Watch=true)] |
\ No newline at end of file |
@@ -28,4 +28,4 @@ | ||
28 | 28 | // |
29 | 29 | // You can specify all the values or you can use the default the Revision and |
30 | 30 | // Build Numbers by using the '*' as shown below: |
31 | -[assembly: AssemblyVersion("1.0.27")] | |
31 | +[assembly: AssemblyVersion("1.0.28")] |
@@ -0,0 +1,107 @@ | ||
1 | +/* | |
2 | + * EventWatch | |
3 | + * Copyright(C) 2019 BananaJinn. | |
4 | + */ | |
5 | +namespace EWatchUI | |
6 | +{ | |
7 | + partial class ActionTeamsEditControl | |
8 | + { | |
9 | + /// <summary> | |
10 | + /// Designer variable used to keep track of non-visual components. | |
11 | + /// </summary> | |
12 | + private System.ComponentModel.IContainer components = null; | |
13 | + private System.Windows.Forms.TextBox textBoxThemeColor; | |
14 | + private System.Windows.Forms.Label label3; | |
15 | + private System.Windows.Forms.TextBox textBoxUrl; | |
16 | + private System.Windows.Forms.Label label1; | |
17 | + private System.Windows.Forms.Label label2; | |
18 | + | |
19 | + /// <summary> | |
20 | + /// Disposes resources used by the control. | |
21 | + /// </summary> | |
22 | + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |
23 | + protected override void Dispose(bool disposing) | |
24 | + { | |
25 | + if (disposing) { | |
26 | + if (components != null) { | |
27 | + components.Dispose(); | |
28 | + } | |
29 | + } | |
30 | + base.Dispose(disposing); | |
31 | + } | |
32 | + | |
33 | + /// <summary> | |
34 | + /// This method is required for Windows Forms designer support. | |
35 | + /// Do not change the method contents inside the source code editor. The Forms designer might | |
36 | + /// not be able to load this method if it was changed manually. | |
37 | + /// </summary> | |
38 | + private void InitializeComponent() | |
39 | + { | |
40 | + this.textBoxThemeColor = new System.Windows.Forms.TextBox(); | |
41 | + this.label3 = new System.Windows.Forms.Label(); | |
42 | + this.textBoxUrl = new System.Windows.Forms.TextBox(); | |
43 | + this.label1 = new System.Windows.Forms.Label(); | |
44 | + this.label2 = new System.Windows.Forms.Label(); | |
45 | + this.SuspendLayout(); | |
46 | + // | |
47 | + // textBoxThemeColor | |
48 | + // | |
49 | + this.textBoxThemeColor.Location = new System.Drawing.Point(109, 29); | |
50 | + this.textBoxThemeColor.Name = "textBoxThemeColor"; | |
51 | + this.textBoxThemeColor.Size = new System.Drawing.Size(120, 19); | |
52 | + this.textBoxThemeColor.TabIndex = 15; | |
53 | + // | |
54 | + // label3 | |
55 | + // | |
56 | + this.label3.Location = new System.Drawing.Point(3, 29); | |
57 | + this.label3.Margin = new System.Windows.Forms.Padding(3); | |
58 | + this.label3.Name = "label3"; | |
59 | + this.label3.Size = new System.Drawing.Size(100, 21); | |
60 | + this.label3.TabIndex = 14; | |
61 | + this.label3.Text = "ThemeColor"; | |
62 | + this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight; | |
63 | + // | |
64 | + // textBoxUrl | |
65 | + // | |
66 | + this.textBoxUrl.Location = new System.Drawing.Point(109, 2); | |
67 | + this.textBoxUrl.Name = "textBoxUrl"; | |
68 | + this.textBoxUrl.Size = new System.Drawing.Size(388, 19); | |
69 | + this.textBoxUrl.TabIndex = 11; | |
70 | + // | |
71 | + // label1 | |
72 | + // | |
73 | + this.label1.Location = new System.Drawing.Point(3, 2); | |
74 | + this.label1.Margin = new System.Windows.Forms.Padding(3); | |
75 | + this.label1.Name = "label1"; | |
76 | + this.label1.Size = new System.Drawing.Size(100, 21); | |
77 | + this.label1.TabIndex = 10; | |
78 | + this.label1.Text = "Webhook URL"; | |
79 | + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; | |
80 | + // | |
81 | + // label2 | |
82 | + // | |
83 | + this.label2.Location = new System.Drawing.Point(235, 29); | |
84 | + this.label2.Margin = new System.Windows.Forms.Padding(3); | |
85 | + this.label2.Name = "label2"; | |
86 | + this.label2.Size = new System.Drawing.Size(192, 21); | |
87 | + this.label2.TabIndex = 16; | |
88 | + this.label2.Text = "(RRGGBB)"; | |
89 | + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; | |
90 | + // | |
91 | + // ActionTeamsEditControl | |
92 | + // | |
93 | + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); | |
94 | + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |
95 | + this.Controls.Add(this.label2); | |
96 | + this.Controls.Add(this.textBoxThemeColor); | |
97 | + this.Controls.Add(this.label3); | |
98 | + this.Controls.Add(this.textBoxUrl); | |
99 | + this.Controls.Add(this.label1); | |
100 | + this.Name = "ActionTeamsEditControl"; | |
101 | + this.Size = new System.Drawing.Size(500, 138); | |
102 | + this.ResumeLayout(false); | |
103 | + this.PerformLayout(); | |
104 | + | |
105 | + } | |
106 | + } | |
107 | +} |
@@ -0,0 +1,40 @@ | ||
1 | +/* | |
2 | + * EventWatch | |
3 | + * Copyright(C) 2019 BananaJinn. | |
4 | + */ | |
5 | +using System; | |
6 | +using System.ComponentModel; | |
7 | +using System.Drawing; | |
8 | +using System.Windows.Forms; | |
9 | +using EWatch.Actions; | |
10 | + | |
11 | +namespace EWatchUI | |
12 | +{ | |
13 | + /// <summary> | |
14 | + /// Description of ActionTeamsEditControl. | |
15 | + /// </summary> | |
16 | + public partial class ActionTeamsEditControl : UserControl | |
17 | + { | |
18 | + public ActionTeamsEditControl() | |
19 | + { | |
20 | + // | |
21 | + // The InitializeComponent() call is required for Windows Forms designer support. | |
22 | + // | |
23 | + InitializeComponent(); | |
24 | + } | |
25 | + | |
26 | + public void SetData(ActionTeams action) | |
27 | + { | |
28 | + textBoxUrl.Text = action.URL; | |
29 | + textBoxThemeColor.Text = action.ThemeColor; | |
30 | + } | |
31 | + | |
32 | + public ActionTeams GetData() | |
33 | + { | |
34 | + return new ActionTeams { | |
35 | + URL = textBoxUrl.Text, | |
36 | + ThemeColor = textBoxThemeColor.Text, | |
37 | + }; | |
38 | + } | |
39 | + } | |
40 | +} |
@@ -57,7 +57,7 @@ | ||
57 | 57 | // buttonOK |
58 | 58 | // |
59 | 59 | this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); |
60 | - this.buttonOK.Location = new System.Drawing.Point(326, 260); | |
60 | + this.buttonOK.Location = new System.Drawing.Point(352, 260); | |
61 | 61 | this.buttonOK.Name = "buttonOK"; |
62 | 62 | this.buttonOK.Size = new System.Drawing.Size(75, 21); |
63 | 63 | this.buttonOK.TabIndex = 11; |
@@ -69,7 +69,7 @@ | ||
69 | 69 | // |
70 | 70 | this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); |
71 | 71 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; |
72 | - this.buttonCancel.Location = new System.Drawing.Point(407, 260); | |
72 | + this.buttonCancel.Location = new System.Drawing.Point(433, 260); | |
73 | 73 | this.buttonCancel.Name = "buttonCancel"; |
74 | 74 | this.buttonCancel.Size = new System.Drawing.Size(75, 21); |
75 | 75 | this.buttonCancel.TabIndex = 12; |
@@ -80,9 +80,9 @@ | ||
80 | 80 | // |
81 | 81 | this.label9.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); |
82 | 82 | this.label9.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; |
83 | - this.label9.Location = new System.Drawing.Point(12, 255); | |
83 | + this.label9.Location = new System.Drawing.Point(13, 255); | |
84 | 84 | this.label9.Name = "label9"; |
85 | - this.label9.Size = new System.Drawing.Size(470, 2); | |
85 | + this.label9.Size = new System.Drawing.Size(500, 2); | |
86 | 86 | this.label9.TabIndex = 10; |
87 | 87 | // |
88 | 88 | // comboBoxType |
@@ -108,7 +108,7 @@ | ||
108 | 108 | // |
109 | 109 | this.panel1.Location = new System.Drawing.Point(13, 37); |
110 | 110 | this.panel1.Name = "panel1"; |
111 | - this.panel1.Size = new System.Drawing.Size(469, 176); | |
111 | + this.panel1.Size = new System.Drawing.Size(500, 176); | |
112 | 112 | this.panel1.TabIndex = 4; |
113 | 113 | // |
114 | 114 | // label2 |
@@ -184,7 +184,7 @@ | ||
184 | 184 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); |
185 | 185 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; |
186 | 186 | this.CancelButton = this.buttonCancel; |
187 | - this.ClientSize = new System.Drawing.Size(499, 290); | |
187 | + this.ClientSize = new System.Drawing.Size(525, 290); | |
188 | 188 | this.Controls.Add(this.textBoxName); |
189 | 189 | this.Controls.Add(this.label5); |
190 | 190 | this.Controls.Add(this.label4); |
@@ -36,6 +36,7 @@ | ||
36 | 36 | private const string TYPE_SYSLOG = "syslog"; |
37 | 37 | private const string TYPE_MANTIS = "mantis"; |
38 | 38 | private const string TYPE_SLACK = "slack"; |
39 | + private const string TYPE_TEAMS = "teams"; | |
39 | 40 | private const string TYPE_REDMINE = "redmine"; |
40 | 41 | private const string TYPE_FORWARD = "forward"; |
41 | 42 |
@@ -44,6 +45,7 @@ | ||
44 | 45 | private ActionSyslogEditControl editSyslog; |
45 | 46 | private ActionMantisEditControl editMantis; |
46 | 47 | private ActionSlackEditControl editSlack; |
48 | + private ActionTeamsEditControl editTeams; | |
47 | 49 | private ActionRedmineEditControl editRedmine; |
48 | 50 | private ActionForwardEditControl editForward; |
49 | 51 |
@@ -60,6 +62,7 @@ | ||
60 | 62 | comboBoxType.Items.Add(TYPE_SYSLOG); |
61 | 63 | comboBoxType.Items.Add(TYPE_MANTIS); |
62 | 64 | comboBoxType.Items.Add(TYPE_SLACK); |
65 | + comboBoxType.Items.Add(TYPE_TEAMS); | |
63 | 66 | comboBoxType.Items.Add(TYPE_REDMINE); |
64 | 67 | comboBoxType.Items.Add(TYPE_FORWARD); |
65 | 68 | editExecute = new ActionExecuteEditControl(); |
@@ -67,6 +70,7 @@ | ||
67 | 70 | editSyslog = new ActionSyslogEditControl(); |
68 | 71 | editMantis = new ActionMantisEditControl(); |
69 | 72 | editSlack = new ActionSlackEditControl(); |
73 | + editTeams = new ActionTeamsEditControl(); | |
70 | 74 | editRedmine = new ActionRedmineEditControl(); |
71 | 75 | editForward = new ActionForwardEditControl(); |
72 | 76 | panel1.Controls.Add(editExecute); |
@@ -74,6 +78,7 @@ | ||
74 | 78 | panel1.Controls.Add(editSyslog); |
75 | 79 | panel1.Controls.Add(editMantis); |
76 | 80 | panel1.Controls.Add(editSlack); |
81 | + panel1.Controls.Add(editTeams); | |
77 | 82 | panel1.Controls.Add(editRedmine); |
78 | 83 | panel1.Controls.Add(editForward); |
79 | 84 | SetPanelVisible(); |
@@ -90,6 +95,7 @@ | ||
90 | 95 | if(Action is ActionSyslog){ editSyslog.SetData((ActionSyslog)Action); } |
91 | 96 | if(Action is ActionMantis){ editMantis.SetData((ActionMantis)Action); } |
92 | 97 | if(Action is ActionSlack){ editSlack.SetData((ActionSlack)Action); } |
98 | + if(Action is ActionTeams){ editTeams.SetData((ActionTeams)Action); } | |
93 | 99 | if(Action is ActionRedmine){ editRedmine.SetData((ActionRedmine)Action); } |
94 | 100 | if(Action is ActionForward){ editForward.SetData((ActionForward)Action); } |
95 | 101 | } |
@@ -125,6 +131,7 @@ | ||
125 | 131 | editSyslog.Visible = TYPE_SYSLOG.Equals(comboBoxType.Text); |
126 | 132 | editMantis.Visible = TYPE_MANTIS.Equals(comboBoxType.Text); |
127 | 133 | editSlack.Visible = TYPE_SLACK.Equals(comboBoxType.Text); |
134 | + editTeams.Visible = TYPE_TEAMS.Equals(comboBoxType.Text); | |
128 | 135 | editRedmine.Visible = TYPE_REDMINE.Equals(comboBoxType.Text); |
129 | 136 | editForward.Visible = TYPE_FORWARD.Equals(comboBoxType.Text); |
130 | 137 | } |
@@ -162,6 +169,9 @@ | ||
162 | 169 | else if(TYPE_SLACK.Equals(type)){ |
163 | 170 | action = editSlack.GetData(); |
164 | 171 | } |
172 | + else if(TYPE_TEAMS.Equals(type)){ | |
173 | + action = editTeams.GetData(); | |
174 | + } | |
165 | 175 | else if(TYPE_REDMINE.Equals(type)){ |
166 | 176 | action = editRedmine.GetData(); |
167 | 177 | } |
@@ -28,4 +28,4 @@ | ||
28 | 28 | // |
29 | 29 | // You can specify all the values or you can use the default the Revision and |
30 | 30 | // Build Numbers by using the '*' as shown below: |
31 | -[assembly: AssemblyVersion("1.0.27")] | |
31 | +[assembly: AssemblyVersion("1.0.28")] |
@@ -28,4 +28,4 @@ | ||
28 | 28 | // |
29 | 29 | // You can specify all the values or you can use the default the Revision and |
30 | 30 | // Build Numbers by using the '*' as shown below: |
31 | -[assembly: AssemblyVersion("1.0.27")] | |
31 | +[assembly: AssemblyVersion("1.0.28")] |