Skip to content

Commit 61cbbce

Browse files
authored
Merge pull request #72 from graylog-labs/aenima4six2/71
Aenima4six2/71
2 parents b7602fa + bb798d6 commit 61cbbce

File tree

11 files changed

+239
-85
lines changed

11 files changed

+239
-85
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>org.graylog.plugins</groupId>
88
<artifactId>graylog-plugin-slack</artifactId>
9-
<version>3.0.1</version>
9+
<version>3.1.0</version>
1010
<packaging>jar</packaging>
1111

1212
<name>${project.artifactId}</name>

screenshot.png

-313 KB
Loading

screenshot2.png

113 KB
Loading

src/main/java/org/graylog2/plugins/slack/SlackClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public void send(SlackMessage message) throws SlackClientException {
5858
}
5959

6060
try (final Writer writer = new OutputStreamWriter(conn.getOutputStream())) {
61-
writer.write(message.getJsonString());
61+
String json = message.getJsonString();
62+
writer.write(json);
6263
writer.flush();
6364

6465
final int responseCode = conn.getResponseCode();

src/main/java/org/graylog2/plugins/slack/SlackMessage.java

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import com.fasterxml.jackson.annotation.JsonProperty;
77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9-
import com.google.common.collect.ImmutableList;
109
import com.google.common.collect.Lists;
1110

11+
import java.util.ArrayList;
1212
import java.util.HashMap;
1313
import java.util.List;
1414
import java.util.Map;
@@ -24,8 +24,8 @@ public class SlackMessage {
2424
private final String iconEmoji;
2525
private final String color;
2626
private final boolean linkNames;
27-
28-
private final List<AttachmentField> attachments;
27+
private final List<AttachmentField> detailFields;
28+
private String customMessage;
2929

3030
public SlackMessage(
3131
String color,
@@ -43,16 +43,16 @@ public SlackMessage(
4343
this.userName = userName;
4444
this.channel = channel;
4545
this.linkNames = linkNames;
46-
this.attachments = Lists.newArrayList();
46+
this.detailFields = Lists.newArrayList();
47+
this.customMessage = null;
4748
}
4849

4950
public String getJsonString() {
5051
// See https://api.slack.com/methods/chat.postMessage for valid parameters
5152
final Map<String, Object> params = new HashMap<String, Object>() {{
5253
put("channel", channel);
5354
put("text", message);
54-
put("link_names", linkNames ? "1" : "0");
55-
put("parse", "none");
55+
put("link_names", linkNames);
5656
}};
5757

5858
if (!isNullOrEmpty(userName)) {
@@ -67,9 +67,30 @@ public String getJsonString() {
6767
params.put("icon_emoji", ensureEmojiSyntax(iconEmoji));
6868
}
6969

70+
final List<Attachment> attachments = new ArrayList<>();
71+
if (!isNullOrEmpty(customMessage)) {
72+
final Attachment attachment = new Attachment(
73+
color,
74+
customMessage,
75+
"Custom Message",
76+
"Custom Message:",
77+
null
78+
);
79+
attachments.add(attachment);
80+
}
81+
82+
if (!detailFields.isEmpty()) {
83+
final Attachment attachment = new Attachment(
84+
color,
85+
null,
86+
"Alert details",
87+
"Alert Details:",
88+
detailFields
89+
);
90+
attachments.add(attachment);
91+
}
92+
7093
if (!attachments.isEmpty()) {
71-
final Attachment attachment = new Attachment("Alert details", null, "Details:", color, attachments);
72-
final List<Attachment> attachments = ImmutableList.of(attachment);
7394
params.put("attachments", attachments);
7495
}
7596

@@ -80,8 +101,12 @@ public String getJsonString() {
80101
}
81102
}
82103

83-
public void addAttachment(AttachmentField attachment) {
84-
this.attachments.add(attachment);
104+
public void addDetailsAttachmentField(AttachmentField attachmentField) {
105+
this.detailFields.add(attachmentField);
106+
}
107+
108+
public void setCustomMessage(String customMessage) {
109+
this.customMessage = customMessage;
85110
}
86111

87112
private String ensureEmojiSyntax(final String x) {
@@ -108,12 +133,12 @@ public static class Attachment {
108133
@JsonProperty
109134
public String pretext;
110135
@JsonProperty
111-
public String color = "good";
136+
public String color;
112137
@JsonProperty
113138
public List<AttachmentField> fields;
114139

115140
@JsonCreator
116-
public Attachment(String fallback, String text, String pretext, String color, List<AttachmentField> fields) {
141+
public Attachment(String color, String text, String fallback, String pretext, List<AttachmentField> fields) {
117142
this.fallback = fallback;
118143
this.text = text;
119144
this.pretext = pretext;
@@ -130,7 +155,7 @@ public static class AttachmentField {
130155
@JsonProperty
131156
public String value;
132157
@JsonProperty("short")
133-
public boolean isShort = false;
158+
public boolean isShort;
134159

135160
@JsonCreator
136161
public AttachmentField(String title, String value, boolean isShort) {

src/main/java/org/graylog2/plugins/slack/SlackPluginBase.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.net.URI;
99
import java.net.URISyntaxException;
1010
import java.util.Arrays;
11+
import java.util.Objects;
1112

1213
public class SlackPluginBase {
1314

@@ -23,7 +24,7 @@ public void setConfiguration(final Configuration config) throws ConfigurationExc
2324
}
2425
}
2526

26-
protected static void checkConfiguration(Configuration configuration) throws ConfigurationException {
27+
protected void checkConfiguration(Configuration configuration) throws ConfigurationException {
2728
if (!configuration.stringIsSet(SlackConfiguration.CK_WEBHOOK_URL)) {
2829
throw new ConfigurationException(SlackConfiguration.CK_WEBHOOK_URL + " is mandatory and must not be empty.");
2930
}
@@ -44,7 +45,7 @@ protected static void checkConfiguration(Configuration configuration) throws Con
4445
private static void checkUri(Configuration configuration, String settingName) throws ConfigurationException {
4546
if (configuration.stringIsSet(settingName)) {
4647
try {
47-
final URI uri = new URI(configuration.getString(settingName));
48+
final URI uri = new URI(Objects.requireNonNull(configuration.getString(settingName)));
4849
if (!isValidUriScheme(uri, "http", "https")) {
4950
throw new ConfigurationException(settingName + " must be a valid HTTP or HTTPS URL.");
5051
}
@@ -67,15 +68,17 @@ protected String buildStreamLink(String baseUrl, Stream stream) {
6768
}
6869

6970
protected static SlackMessage createSlackMessage(Configuration configuration, String message) {
70-
return new SlackMessage(
71-
configuration.getString(SlackConfiguration.CK_COLOR),
72-
configuration.getString(SlackConfiguration.CK_ICON_EMOJI),
73-
configuration.getString(SlackConfiguration.CK_ICON_URL),
74-
message,
75-
configuration.getString(SlackConfiguration.CK_USER_NAME),
76-
configuration.getString(SlackConfiguration.CK_CHANNEL),
77-
configuration.getBoolean(SlackConfiguration.CK_LINK_NAMES)
78-
);
71+
String color = configuration.getString(SlackConfiguration.CK_COLOR);
72+
String emoji = configuration.getString(SlackConfiguration.CK_ICON_EMOJI);
73+
String url = configuration.getString(SlackConfiguration.CK_ICON_URL);
74+
String user = configuration.getString(SlackConfiguration.CK_USER_NAME);
75+
String channel = configuration.getString(SlackConfiguration.CK_CHANNEL);
76+
77+
//Note: Link names if notify channel or else the channel tag will be plain text.
78+
boolean linkNames = configuration.getBoolean(SlackConfiguration.CK_LINK_NAMES) ||
79+
configuration.getBoolean(SlackConfiguration.CK_NOTIFY_CHANNEL);
80+
81+
return new SlackMessage(color, emoji, url, message, user, channel, linkNames);
7982
}
8083

8184
protected String buildMessageLink(String baseUrl, String index, String id) {
@@ -85,5 +88,4 @@ protected String buildMessageLink(String baseUrl, String index, String id) {
8588

8689
return baseUrl + "messages/" + index + "/" + id;
8790
}
88-
8991
}

src/main/java/org/graylog2/plugins/slack/callback/SlackAlarmCallback.java

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.graylog2.plugin.alarms.AlertCondition;
99
import org.graylog2.plugin.alarms.callbacks.AlarmCallback;
1010
import org.graylog2.plugin.alarms.callbacks.AlarmCallbackConfigurationException;
11-
import org.graylog2.plugin.alarms.callbacks.AlarmCallbackException;
1211
import org.graylog2.plugin.configuration.Configuration;
1312
import org.graylog2.plugin.configuration.ConfigurationException;
1413
import org.graylog2.plugin.configuration.ConfigurationRequest;
@@ -45,23 +44,28 @@ public void initialize(final Configuration config) throws AlarmCallbackConfigura
4544
}
4645

4746
@Override
48-
public void call(Stream stream, AlertCondition.CheckResult result) throws AlarmCallbackException {
49-
47+
public void call(Stream stream, AlertCondition.CheckResult result) {
5048
final SlackClient client = new SlackClient(configuration);
51-
SlackMessage message = createSlackMessage(configuration, buildFullMessageBody(stream, result));
49+
String text = buildFullMessageBody(stream, result);
50+
SlackMessage slackMessage = createSlackMessage(configuration, text);
51+
52+
// Add custom message
53+
String template = configuration.getString(SlackConfiguration.CK_CUSTOM_MESSAGE);
54+
boolean hasTemplate = !isNullOrEmpty(template);
55+
if (hasTemplate) {
56+
String customMessage = buildCustomMessage(stream, result, template);
57+
slackMessage.setCustomMessage(customMessage);
58+
}
5259

5360
try {
54-
client.send(message);
61+
client.send(slackMessage);
5562
} catch (SlackClient.SlackClientException e) {
5663
throw new RuntimeException("Could not send message to Slack.", e);
5764
}
5865
}
5966

60-
6167
private String buildFullMessageBody(Stream stream, AlertCondition.CheckResult result) {
6268
String graylogUri = configuration.getString(SlackConfiguration.CK_GRAYLOG2_URL);
63-
boolean notifyChannel = configuration.getBoolean(SlackConfiguration.CK_NOTIFY_CHANNEL);
64-
6569
String titleLink;
6670
if (!isNullOrEmpty(graylogUri)) {
6771
titleLink = "<" + buildStreamLink(graylogUri, stream) + "|" + stream.getTitle() + ">";
@@ -70,19 +74,12 @@ private String buildFullMessageBody(Stream stream, AlertCondition.CheckResult re
7074
}
7175

7276
// Build custom message
73-
StringBuilder message = new StringBuilder(result.getResultDescription()).append("\n");
74-
String template = configuration.getString(SlackConfiguration.CK_CUSTOM_MESSAGE);
75-
if (!isNullOrEmpty(template)) {
76-
String customMessage = buildCustomMessage(stream, result, template);
77-
message.append("\n").append(customMessage);
78-
}
79-
77+
boolean notifyChannel = configuration.getBoolean(SlackConfiguration.CK_NOTIFY_CHANNEL);
8078
String audience = notifyChannel ? "@channel " : "";
81-
return String.format("%s*Alert for Graylog stream %s*:\n> %s",
82-
audience, titleLink, message.toString());
79+
String description = result.getResultDescription();
80+
return String.format("%s*Alert for Graylog stream %s*:\n> %s \n", audience, titleLink, description);
8381
}
8482

85-
8683
private String buildCustomMessage(Stream stream, AlertCondition.CheckResult result, String template) {
8784
List<Message> backlog = getAlarmBacklog(result);
8885
Map<String, Object> model = getModel(stream, result, backlog);
@@ -129,7 +126,7 @@ public Map<String, Object> getAttributes() {
129126
}
130127

131128
@Override
132-
public void checkConfiguration() throws ConfigurationException {
129+
public void checkConfiguration() {
133130
/* Never actually called by graylog-server */
134131
}
135132

src/main/java/org/graylog2/plugins/slack/configuration/SlackConfiguration.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ public class SlackConfiguration {
1414
public static final String CK_SHORT_MODE = "short_mode";
1515
public static final String CK_ADD_BLITEMS = "backlog_items";
1616
public static final String CK_CUSTOM_MESSAGE = "custom_message";
17+
public static final String CK_ADD_DETAILS = "add_details";
1718
}

src/main/java/org/graylog2/plugins/slack/configuration/SlackConfigurationRequestFactory.java

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,93 @@
99
public class SlackConfigurationRequestFactory {
1010

1111
public static ConfigurationRequest createSlackMessageOutputConfigurationRequest() {
12-
final ConfigurationRequest configurationRequest = createSlackAlarmCallbackConfigurationRequest();
12+
final ConfigurationRequest configurationRequest = new ConfigurationRequest();
13+
configurationRequest.addField(new TextField(
14+
SlackConfiguration.CK_COLOR, "Custom Message & Additional Info Color", "#FF0000",
15+
"Color to use for Slack custom message and additional information attachments",
16+
ConfigurationField.Optional.NOT_OPTIONAL)
17+
);
18+
configurationRequest.addField(new TextField(
19+
SlackConfiguration.CK_CUSTOM_MESSAGE, "Custom Message",
20+
"##########\n" +
21+
"Date: ${check_result.triggeredAt}\n" +
22+
"Stream ID: ${stream.id}\n" +
23+
"Stream title: ${stream.title}\n" +
24+
"Stream description: ${stream.description}\n" +
25+
"${if stream_url}Stream URL: ${stream_url}${end}\n" +
26+
"##########\n",
27+
"Custom message to be appended below the alert title. " +
28+
"The following properties are available for template building: " +
29+
"\"stream\", " +
30+
"\"message\", " +
31+
" \"stream_url\"," +
32+
"See http://docs.graylog.org/en/2.3/pages/streams/alerts.html#email-alert-notification for more details.",
33+
ConfigurationField.Optional.OPTIONAL,
34+
TextField.Attribute.TEXTAREA)
35+
);
36+
37+
configurationRequest.addField(new TextField(
38+
SlackConfiguration.CK_WEBHOOK_URL, "Webhook URL", "", "Slack \"Incoming Webhook\" URL",
39+
ConfigurationField.Optional.NOT_OPTIONAL)
40+
);
41+
configurationRequest.addField(new TextField(
42+
SlackConfiguration.CK_CHANNEL, "Channel", "#channel", "Name of Slack #channel or @user for a direct message.",
43+
ConfigurationField.Optional.NOT_OPTIONAL)
44+
);
45+
configurationRequest.addField(new TextField(
46+
SlackConfiguration.CK_USER_NAME, "User name", "Graylog",
47+
"User name of the sender in Slack",
48+
ConfigurationField.Optional.OPTIONAL)
49+
);
50+
configurationRequest.addField(new BooleanField(
51+
SlackConfiguration.CK_NOTIFY_CHANNEL, "Notify Channel", false,
52+
"Notify all users in channel by adding @channel to the message.")
53+
);
54+
configurationRequest.addField(new BooleanField(
55+
SlackConfiguration.CK_LINK_NAMES, "Link names", true,
56+
"Find and link channel names and user names")
57+
);
58+
configurationRequest.addField(new TextField(
59+
SlackConfiguration.CK_ICON_URL, "Icon URL", null,
60+
"Image to use as the icon for this message",
61+
ConfigurationField.Optional.OPTIONAL)
62+
);
63+
configurationRequest.addField(new TextField(
64+
SlackConfiguration.CK_ICON_EMOJI, "Icon Emoji", null,
65+
"Emoji to use as the icon for this message (overrides Icon URL)",
66+
ConfigurationField.Optional.OPTIONAL)
67+
);
68+
configurationRequest.addField(new TextField(
69+
SlackConfiguration.CK_GRAYLOG2_URL, "Graylog URL", null,
70+
"URL to your Graylog web interface. Used to build links in alarm notification.",
71+
ConfigurationField.Optional.OPTIONAL)
72+
);
73+
configurationRequest.addField(new TextField(
74+
SlackConfiguration.CK_PROXY_ADDRESS, "Proxy", null,
75+
"Please insert the proxy information in the follwoing format: <ProxyAddress>:<Port>",
76+
ConfigurationField.Optional.OPTIONAL)
77+
);
1378
configurationRequest.addField(new BooleanField(
1479
SlackConfiguration.CK_SHORT_MODE, "Short mode", false,
1580
"Enable short mode? This strips down the Slack message to the bare minimum to take less space in the chat room. " +
1681
"Not used in alarm callback but only in the message output module.")
1782
);
83+
configurationRequest.addField(new BooleanField(
84+
SlackConfiguration.CK_ADD_DETAILS, "Include more information", true,
85+
"Add structured information as message attachment")
86+
);
1887

1988
return configurationRequest;
2089
}
2190

2291
public static ConfigurationRequest createSlackAlarmCallbackConfigurationRequest() {
2392
final ConfigurationRequest configurationRequest = new ConfigurationRequest();
2493

94+
configurationRequest.addField(new TextField(
95+
SlackConfiguration.CK_COLOR, "Custom Message Color", "#FF0000",
96+
"Color to use for Slack custom message",
97+
ConfigurationField.Optional.NOT_OPTIONAL)
98+
);
2599
configurationRequest.addField(new TextField(
26100
SlackConfiguration.CK_CUSTOM_MESSAGE, "Custom Message",
27101
"##########\n" +
@@ -67,11 +141,6 @@ public static ConfigurationRequest createSlackAlarmCallbackConfigurationRequest(
67141
"User name of the sender in Slack",
68142
ConfigurationField.Optional.OPTIONAL)
69143
);
70-
configurationRequest.addField(new TextField(
71-
SlackConfiguration.CK_COLOR, "Color", "#FF0000",
72-
"Color to use for Slack message",
73-
ConfigurationField.Optional.NOT_OPTIONAL)
74-
);
75144
configurationRequest.addField(new NumberField(
76145
SlackConfiguration.CK_ADD_BLITEMS, "Backlog items", 5,
77146
"Number of backlog item descriptions to attach")

0 commit comments

Comments
 (0)