Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerd Naschenweng committed Mar 9, 2016
0 parents commit 21e5999
Show file tree
Hide file tree
Showing 38 changed files with 1,595 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
29 changes: 29 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Graylog Jira Callback</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>
5 changes: 5 additions & 0 deletions .settings/org.eclipse.core.resources.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
5 changes: 5 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
4 changes: 4 additions & 0 deletions .settings/org.eclipse.m2e.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Graylog Plugin for JIRA with templating

An alarm callback plugin that integrates [Graylog](https://www.graylog.org/) into [JIRA](https://www.atlassian.com/software/jira/).

# Pre-requisites for Java exception logging
-------------------------------------------
If you use an application server such as Tomcat, we suggest that you use [Logstash](https://www.elastic.co/products/logstash) to pre-process your log-files and ship the log-records via Gelf output into Graylog.

A very reliable way of processing Tomcat logs can be achieved by:

* Using Logstash with `sincedb_path` and `sincedb_write_interval`
* Use Log4J to consistently format log records to consist of `%{LOGLEVEL} %{timestamp} %{threadname} %{MESSAGE}`
* Use a multi-line codec to extract exception messages
* Use a series of grok patterns to retag multiline messages as "exception" you want a Graylog stream to process - i.e. `match => { message => [ "(^.+Exception: .+)|(^.+Stacktrace:.+)" ] }`
* Discard and sanitize messages in Logstash - this will improve storage, filtering and stream processing

With the above you can easily setup a stream where your condition is as simple as "`type must match exactly tomcat AND tags must match exactly exception`"



Installation of plugin
----------------------
This plugin has been tested with Graylog v1.3.3 and JIRA v7.0.10.

Download the [latest release](https://github.com/magicdude4eva/XXXX/releases) and copy the `.jar` file into your Graylog plugin directory (default is in `/usr/share/graylog-server/plugin`).
If you are unsure about the plugin location, do a `grep -i plugin_dir /etc/graylog/server/server.conf`.

Restart Graylog via `systemctl restart graylog-server`

Configuration
-------------

### Create a "JIRA Alarm Callback" in Graylog and configure your alert conditions:
![Graylog alert conditions](./screenshot-alert-conditions.png)

### Configure the callback configuration
![Graylog callback configuration](./screenshot-alert.png)

### Callback options
* __JIRA Instance URL__: The URL to your JIRA server
* __Project Key__: The project key under which the issue will be created in JIRA
* __Issue Type__: The JIRA issue type (defaults to `Bug`). Ensure that the issue type matches your project settings
* __Graylog URL__: The URL to the Graylog web-interface. The URL is used to generate links within JIRA
* __Issue Priority__: The JIRA issue priority (defaults to `Minor`). Ensure that the issue priority matches your project settings
* __Labels__: Comma-separated list of labels to add to the issue
* __Message template__: Message template used to create a JIRA issue. The message template uses JIRA Text Formatting Notation. Line-breaks can be added as "`\n`". The message-template also accepts `[PLACEHOLDERS]`
* __[STREAM_TITLE]__: Title of the stream
* __[STREAM_URL]__: URL to the stream
* __[STREAM_RULES]__: Stream rules triggered
* __[ALERT_TRIGGERED_AT]__: Timestamp when alert was triggered
* __[ALERT_TRIGGERED_CONDITION]__: Conditions triggering the alert
* __[LAST_MESSAGE.SOURCE]__: If a message is present, the placeholder will be replaced with the source origin of the message
* __[LAST_MESSAGE.MESSAGE]__: The actual message
* __[LAST_MESSAGE.FIELDNAME]__: Replaces with any field in the logged record. i.e. "`[LAST_MESSAGE.PATH]`" would display the full logpath where the message originated from.
* __JIRA task title__: Sets the title of the JIRA task. Can include `[MESSAGE_REGEX]`(see __Message regex__). Can also include any field via `[LAST_MESSAGE.FIELDNAME]`
* __Message regex__: A regular expression to extract a portion of the message. This is used to extract an exception message as well as to generate a MD5 hash to identify duplicate JIRA issues.


### Callback examples

If a log-message contains:
```
H/M 07/03/16 15:37:23 tcbobe-56 OrderStructureIO java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (PRODZA.ORDERS_PK) violated
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1150)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:4875)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1361)
```

With the following settings:
* __Message regex__ = `([a-zA-Z_.]+(?!.*Exception): .+)`
* __JIRA task title__ = `[Graylog-[LAST_MESSAGE.SOURCE]] [MESSAGE_REGEX]`
* __Message template__ = `*Alert triggered at:* \n [ALERT_TRIGGERED_AT]\n\n *Stream URL:* \n [STREAM_URL]\n\n*Source:* \n [LAST_MESSAGE.SOURCE]\n\n *Message:* \n [LAST_MESSAGE.MESSAGE]\n\n`

The JIRA issue will be logged follows:
![JIRA issue](./screenshot-jira.png)

## Copyright

Original idea from https://github.com/tjackiw/graylog-plugin-jira
209 changes: 209 additions & 0 deletions dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bidorbuy.graylog</groupId>
<artifactId>graylog-plugin-jira</artifactId>
<name>${project.artifactId}</name>
<version>1.0.0</version>
<description>Graylog ${project.artifactId} plugin.</description>
<url>https://www.graylog.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer />
</transformers>
</configuration>
</execution>
</executions>
<configuration>
<minimizeJar>false</minimizeJar>
</configuration>
</plugin>
<plugin>
<groupId>org.vafer</groupId>
<artifactId>jdeb</artifactId>
<version>1.3</version>
<configuration>
<deb>${project.build.directory}/${project.artifactId}-${project.version}.deb</deb>
<dataSet>
<data>
<src>${project.build.directory}/${project.build.finalName}.jar</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>${graylog2.plugin-dir}</prefix>
<filemode>644</filemode>
<user>root</user>
<group>root</group>
</mapper>
</data>
</dataSet>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.1.2</version>
<configuration>
<group>Application/Internet</group>
<prefixes>
<prefix>/usr</prefix>
</prefixes>
<defineStatements>
<defineStatement>_unpackaged_files_terminate_build 0</defineStatement>
<defineStatement>_binaries_in_noarch_packages_terminate_build 0</defineStatement>
</defineStatements>
<defaultFilemode>644</defaultFilemode>
<defaultDirmode>755</defaultDirmode>
<defaultUsername>root</defaultUsername>
<defaultGroupname>root</defaultGroupname>
<mappings>
<mapping>
<directory>${graylog2.plugin-dir}</directory>
<sources>
<source>
<location>${project.build.directory}/</location>
<includes>
<include>${project.build.finalName}.jar</include>
</includes>
</source>
</sources>
</mapping>
</mappings>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.graylog2</groupId>
<artifactId>graylog2-plugin</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>guice-assistedinject</artifactId>
<groupId>com.google.inject.extensions</groupId>
</exclusion>
<exclusion>
<artifactId>joda-time</artifactId>
<groupId>joda-time</groupId>
</exclusion>
<exclusion>
<artifactId>metrics-core</artifactId>
<groupId>io.dropwizard.metrics</groupId>
</exclusion>
<exclusion>
<artifactId>disruptor</artifactId>
<groupId>com.lmax</groupId>
</exclusion>
<exclusion>
<artifactId>guice</artifactId>
<groupId>com.google.inject</groupId>
</exclusion>
<exclusion>
<artifactId>guice-multibindings</artifactId>
<groupId>com.google.inject.extensions</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-core</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-databind</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
<exclusion>
<artifactId>javax.ws.rs-api</artifactId>
<groupId>javax.ws.rs</groupId>
</exclusion>
<exclusion>
<artifactId>msgpack</artifactId>
<groupId>org.msgpack</groupId>
</exclusion>
<exclusion>
<artifactId>protobuf-java</artifactId>
<groupId>com.google.protobuf</groupId>
</exclusion>
<exclusion>
<artifactId>netty</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-common</artifactId>
<groupId>org.glassfish.jersey.core</groupId>
</exclusion>
<exclusion>
<artifactId>kie-api</artifactId>
<groupId>org.kie</groupId>
</exclusion>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
<exclusion>
<artifactId>uuid</artifactId>
<groupId>com.eaio.uuid</groupId>
</exclusion>
<exclusion>
<artifactId>jadconfig</artifactId>
<groupId>com.github.joschi</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.10</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<graylog2.plugin-dir>/usr/share/graylog-server/plugin</graylog2.plugin-dir>
<graylog2.version>1.0.0</graylog2.version>
<maven.compiler.source>1.7</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
</project>

Loading

0 comments on commit 21e5999

Please sign in to comment.