How to monitor remote JVM applications with `logback-webhook-appender`.
Tags: sip3, java, kotlin, logging
Published: 2020-04-20 09:50:20

# Overview

This tutorial is for anyone who is actively using logback in their JVM applications. For those who are not familiar with the framework, I strongly recommend checking out its [documentation](http://logback.qos.ch).

Out-of-the-box logback can send `WARNING` and `ERROR` logging events via [email](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/SMTPAppender.html). Sometimes receiving those events is the best way to monitor and debug remote applications. However, email as notifications channel isn't that attractive. That's why the [SIP3](https://sip3.io) team wrote a handy [logback extension](https://github.com/sip3io/logback-webhook-appender) that uses webhooks and makes it possible to send the same events to unlimited amount of channels including the most popular -  Slack and Telegram.

In this tutorial we will build a simple Spring Boot application and configure it to start sending `ERROR` messages via [Incoming Webhook](https://slack.com/intl/en-ru/help/articles/115005265063-Incoming-Webhooks-for-Slack) for Slack.

### 1. Creating Spring Boot Application

Open [Spring Initializr](https://start.spring.io/) project to create a dummy Spring Boot application:

![Spring Initializr](https://dev-to-uploads.s3.amazonaws.com/i/o5ljyq44ivfcshr7lm0y.png)

Let's choose Kotlin and press the `GENERATE` button.

For this showcase we will add some code in the DemoApplication class:

```kotlin
@SpringBootApplication
class DemoApplication {

	private val logger: Logger = LoggerFactory.getLogger(DemoApplication::class.java)

	@PostConstruct
	fun init() {
		try {
		    throw RuntimeException("Houston, we have a problem!")
		} catch (e: Exception) {
			logger.error("Got exception...", e)
		}		
	}
}

fun main(args: Array<String>) {
	runApplication<DemoApplication>(*args)
}
```

As you can see the code above throws RuntimeException every time we start the application.

### 2. Adding logback-webhook-appender

Let's pull [logback-webhook-appender](https://github.com/sip3io/logback-webhook-appender) and install it to a local Maven repository using `mvn clean install`. 

Now we can add it as a dependency to the project's `pom.xml`(in some cases you will have to resolve a conflict with okhttp3 library by explicitly specifying its version):

```xml
<properties>
	...
	<okhttp3.version>4.5.0</okhttp3.version>
</properties>

<dependencies>
	...		
	<dependency>
		<groupId>io.sip3</groupId>
		<artifactId>logback-webhook-appender</artifactId>
		<version>1.0.0-SNAPSHOT</version>
	</dependency>	
	...
</dependencies>
```
### 3. Configuring logback-webhook-appender

Prior to the next step we need to [set up an Incoming Webhook](https://slack.com/intl/en-ru/help/articles/115005265063-Incoming-Webhooks-for-Slack) for our Slack.

Once it's done we can create and configure `src/main/resources/logback-spring.xml`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="webhook" class="io.sip3.logback.WebhookAppender">
        <url>https://hooks.slack.com/services/%YOUR_WEBHOOK_URI%</url>     // (1)
        <json>                                                             // (2)
            {
                "text": ":fire: Houston, we have a problem! :fire:",
                "attachments": [
                    {
                        "text": "{message}"                                // (3)
                    }
                ]
            }
        </json>
        <encoder>
            <pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="ERROR">
        <appender-ref ref="webhook"/>
    </root>
</configuration>
```

* (1) - Use `<url>` to set up a webhook URL
* (2) - Use `<json>` to set up a payload template
* (3) - Use `{message}` as a placeholder for encoded logging event

### 4. Testing logback-webhook-appender

So far so good. Let's start our application using `mvn spring-boot:run` command. Then open the configured Slack channel to receive an `ERROR` notification:

![Slack `ERROR` Notification](https://dev-to-uploads.s3.amazonaws.com/i/0rf64rbcqyb5dnxh9sv0.png)

And that is how you setup a very simple but useful monitoring in a matter of 2-5 minutes.

I hope you loved the approach and will start using it in your projects. If you have any questions, just leave me a message :)

Cheers...