# Better Stack Java logging

## Start logging in 5 minutes

Collect logs from your Java applications using [Logback](https://logback.qos.ch).

### 1. Dependencies

Add Better Stack Logback appender to your `pom.xml` or `build.gradle` file:

[code-tabs]
```xml
[label Maven (pom.xml)]
<dependency>
    <groupId>com.logtail</groupId>
    <artifactId>logback-logtail</artifactId>
    <version>0.3.3</version>
</dependency>
```
```java
[label Gradle (build.gradle)]
dependencies {
    // ...existing dependencies...
    implementation 'com.logtail:logback-logtail:0.3.3'
}
```
[/code-tabs]

You will need a Logback logger with a data-binding package for Jackson.

**Don't have Logback in your project yet?**  
Add these dependencies to your `pom.xml` or `build.gradle` file:


[code-tabs]
```xml
[label Maven (pom.xml)]
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.11</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.2.11</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.5</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.7</version>
</dependency>
```
```java
[label Gradle (build.gradle)]
dependencies {
    // ...existing dependencies...
    implementation 'ch.qos.logback:logback-classic:1.2.11'
    implementation 'ch.qos.logback:logback-core:1.2.11'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.5'
    implementation 'org.slf4j:slf4j-api:1.7.7'
}
```
[/code-tabs]

### 2. Setup

Set up log appenders in your `logback.xml` configuration:

```xml
[label Logback config]
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="Logtail" class="com.logtail.logback.LogtailAppender">
        <appName>MyApp</appName>
        <sourceToken>$SOURCE_TOKEN</sourceToken>
        <ingestUrl>https://$INGESTING_HOST</ingestUrl >
        <mdcFields>requestId,requestTime</mdcFields>
        <mdcTypes>string,int</mdcTypes>
    </appender>
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="Logtail" />
        <appender-ref ref="Console" />
    </root>
</configuration>
```

### 3. Start logging 🎉

Import and use the logger:

```java
[label Send logs to Logtail]
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(App.class);
        logger.error("Something bad happened.");
        String json = "{ \"item\": \"Orange soda\", \"price\": 100.00 }";
        logger.info("Log message with structured logging " + json);
    }
}
```

You should see your logs in [Better Stack → Live tail](https://telemetry.betterstack.com/team/0/tail ";_blank").  

Find structured data under the `message_json` field.  
Better Stack parses any JSON at the end of the log line.

## Need help?

Please let us know at hello@betterstack.com.  
We're happy to help! 🙏

## Additional information

- **New to logging in Java?** Check out our [Intro guide to logging in Java](https://betterstack.com/community/guides/logging/how-to-start-logging-with-java/). 
- **Want to support more data types?** Install an add-on module for Jackson and register it in the Logtail appender's `<objectMapperModule>` tag.
For example, see [adding JavaTimeModule on Github](https://github.com/logtail/logback-logtail/pull/21/files).
- **Need to fine-tune logging?** Configure more options inside `<appender name="Logtail">` tag in `logback.xml`:
  - `appName` - Application name for Better Stack indexation.
  - `sourceToken ` - Your Better Stack source token.
  - `ingestUrl` - The ingesting URL of your source. Default: `https://in.logs.betterstack.com`. Use the ingesting host listed in your source settings.
  - `mdcFields` - MDC fields that will be sent as metadata, separated by a comma.
  - `mdcTypes` - MDC fields types that will be sent as metadata, in the same order as `mdcFields` are set up, separated by a comma. Possible values are `string`, `boolean`, `int`, and `long`.
  - `maxQueueSize` - Maximum number of messages in the queue. Messages over the limit will be dropped. Default: 100000.
  - `batchSize` - Batch size for the number of messages to be sent via the API. Default: 1000.
  - `batchInterval` - Maximum wait time for a batch to be sent via the API, in milliseconds. Default: 3000.
  - `setConnectTimeout` - Connection timeout of the underlying HTTP client, in milliseconds. Default: 5000.
  - `readTimeout` - Read timeout of the underlying HTTP client, in milliseconds. Default: 10000.
  - `maxRetries` - Maximum number of retries for sending logs to Better Stack. After that, current batch of logs will be dropped. Default: 5.
  - `retrySleepMilliseconds` - Number of milliseconds to sleep before retrying to send logs to Better Stack. Default: 300.
  - `objectMapperModule` - Registers an add-on data type module for Jackson to serialize logged data, e.g. `com.fasterxml.jackson.datatype.jsr310.JavaTimeModule`. Can be used multiple times.

### Example project

Want to try a more detailed example with Maven or Gradle?  
See our [Java Logtail example projects on GitHub](https://github.com/logtail/logback-logtail/tree/master/examples).
