How to Store Spring Boot Application Metrics in InfluxDB
Tags: backend, java, programming, springboot
Published: 2024-03-02 13:11:31

[Spring Boot](https://stackedit.io/%5Bhttps://spring.io/projects/spring-boot/%5D(https://spring.io/projects/spring-boot/)) is rapidly becoming one of the most popular frameworks for building web applications and microservices because it supports declarative programming, can be configured extensively, and has a large community of users ready to help.

In particular, Spring Boot is generally used in enterprises because it's considered one of the most reliable technologies on the market. Specifically, it offers several ways to track events and metrics and monitor what's happening through the [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators).

In this tutorial, you'll learn how to build a Java web application with Spring Boot that collects metrics via the [Micrometer library](https://github.com/micrometer-metrics/micrometer) and automatically sends them to an instance of [InfluxDB](https://www.influxdata.com/), the ideal database for storing this type of data.

## Creating a Spring Boot App to Collect Application Metrics

As previously stated, in this article, you'll learn how to create a Java Spring Boot web application to collect metrics and send them to InfluxDB. Before you begin this tutorial, you'll need the following:

- A valid InfluxDB instance or access to [InfluxDB Cloud](https://stackedit.io/%5Bhttps://www.influxdata.com/products/influxdb-cloud/%5D(https://www.influxdata.com/products/influxdb-cloud/)). (If you don't have this, you can learn how to set it up in the next section.)

- The [Java JDK](https://www.oracle.com/java/technologies/downloads/) version 8 or newer installed on your system.

- An [integrated development environment (IDE)](https://stackedit.io/%5Bhttps://en.wikipedia.org/wiki/Integrated_development_environment%5D(https://en.wikipedia.org/wiki/Integrated_development_environment)) of your choosing.

These are prerequisites for building a Spring Boot web application to manage a publication. This application will expose APIs that allow publication editors to retrieve, create, update, and delete draft posts received from their authors. In addition to providing access to these features, the demo application will use Micrometer to store some useful log metrics in InfluxDB.

If you want to test the demo application you're going to learn how to build, clone the [GitHub repository supporting this tutorial](https://github.com/Tonel/influxdb-spring-boot-demo) with the following command:

```shell
git clone https://github.com/Tonel/influxdb-spring-boot-demo
```

Then run the `DemoApplication` main class by following [this guide in the Spring Boot official documentation](https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/using-boot-running-your-application.html).

Now it's time to build the demo application.

### Set Up InfluxDB

If you don't have access to an InfluxDB database instance, you can [set up an InfluxDB account](https://cloud2.influxdata.com/signup) in order to enter [InfluxDB Cloud](https://www.influxdata.com/products/influxdb-cloud/). This gives you access to an InfluxDB database on the cloud for free:

![InfluxDB sign-up form](https://writech.run/wp-content/uploads/2023/12/image-25.png)

Fill out the sign-up form and continue following the prompts. Select your cloud provider and region, enter your company name, accept the service agreements, and select **Continue**:

![Selecting where to store your data](https://writech.run/wp-content/uploads/2023/12/image-32.png)

At this point, you can choose from three different plans. The free plan is sufficient to build the demo application:

![Choosing the free plan](https://writech.run/wp-content/uploads/2023/12/image-26.png)

Once completed, you'll have access to the InfluxDB platform:

![Getting started with influxDB](https://writech.run/wp-content/uploads/2023/12/image-27.png)

In the left bar, hover over the **Load Data** event and select **API Tokens**:

![Selecting "API Tokens"](https://writech.run/wp-content/uploads/2023/12/image-28.png)

Once selected, you should see the following:

![Creating an API Token](https://writech.run/wp-content/uploads/2023/12/image-33.png)

Click **\+ GENERATE API TOKEN** > **All Access API Token** and click **Save**. An alert containing your API Token should appear:

![API Token created successfully](https://writech.run/wp-content/uploads/2023/12/image-34.png)

Select **COPY TO CLIPBOARD** and store your API Token in a safe place, as you'll need it later on.

### Set Up an InfluxDB Bucket

Now it's time to set up your first [InfluxDB bucket](https://docs.influxdata.com/influxdb/v2.4/reference/cli/influx/bucket/). In the bar on the left, hover over the **Load Data** element again, but this time, select **Buckets**:

![Selecting "Buckets"](https://writech.run/wp-content/uploads/2023/12/image-29.png)

Now you should see the bucket management panel:

![The "Buckets" view](https://writech.run/wp-content/uploads/2023/12/image-30.png)

Click on **\+ CREATE BUCKET** in the upper-right-hand corner and name your new bucket "posts":

![Creating a new bucket](https://writech.run/wp-content/uploads/2023/12/image-31.png)

Select **CREATE**, and now you're ready to start using InfluxDB!

### Initialize a Spring Boot Application

After setting up an InfluxDB bucket, it's time to set up a blank Spring Boot application. Visit [spring initializr](https://stackedit.io/%5Bhttps://start.spring.io/%5D(https://start.spring.io/)) and fill out the following form:

![Initializing a new Spring Boot application](https://writech.run/wp-content/uploads/2023/12/image-35.png)

Select **GENERATE**, and your browser should automatically download a `demo.zip` file. Extract it, and you'll find your Spring Boot blank Maven project. Open the project with your favorite IDE, and you can get started adding some libraries.

### Add the Required Dependencies

To make your Java Spring Boot demo application collect metrics and send them to InfluxDB, you need to download some additional libraries:

- **[`org.springframework.boot:spring-boot-starter-web`](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web):** provides you with everything you need to build microservices in Spring Boot.

- **[`org.springframework.boot:spring-boot-starter-actuator`](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator):** gives you access to production-ready features to monitor your app, gather metrics, and understand traffic. More information about Spring Boot Actuator is available [in Spring Boot's official docs](https://docs.spring.io/spring-boot/docs/current/actuator-api/htmlsingle/).

- **[`org.springframework.boot:spring-boot-starter-data-jpa`](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa):** allows you to store and retrieve data in a relational database.

- **[`com.h2database:h2`](https://mvnrepository.com/artifact/com.h2database/h2):** gives you access to an in-memory [H2 database](https://en.wikipedia.org/wiki/H2_(DBMS)) instance.

Once you've downloaded these libraries, you need to add them to the project's dependencies.

To install these libraries, add the following dependencies to your `pom.xml` file:

```xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>
```

> **Please note:** The H2 database was chosen for simplicity. You can replace it with any other database technology and use the [Spring Boot JPA](https://spring.io/projects/spring-data-jpa) to connect. The demo application will still work.

Keep in mind that the goal of your demo application is to collect metrics and export them to InfluxDB. To achieve this, you need to use the [Micrometer](https://stackedit.io/%5Bhttps://micrometer.io/%5D(https://micrometer.io/)) tool.

#### Install Micrometer

Micrometer is a [dimensional-first metrics-collection tool](https://spring.io/blog/2018/03/16/micrometer-spring-boot-2-s-new-application-metrics-collector) that helps you time, count, and gauge your code. The Spring Boot Actuator supports Micrometer and provides dependency management and auto-configuration.

To install Micrometer, add the following dependencies to your `pom.xml` file:

```xml
<dependency>
	<groupId>io.micrometer</groupId>
	<artifactId>micrometer-core</artifactId>
	<version>1.9.3</version>
</dependency>
<dependency>
	<groupId>io.micrometer</groupId>
	<artifactId>micrometer-registry-influx</artifactId>
	<version>1.9.3</version>
</dependency>
```

[`io.micrometer:micrometer-core`](https://mvnrepository.com/artifact/io.micrometer/micrometer-core) is the core Micrometer dependency, and [`io.micrometer:micrometer-registry-influx`](https://mvnrepository.com/artifact/io.micrometer/micrometer-registry-influx) enables Micrometer to automatically export data to InfluxDB.

Once Micrometer is installed, you can start building your Spring Boot application to store metrics in InfluxDB.

### Build the Demo Application

Before building your Spring Book application, you need to initialize the project structure. This will contain the following packages:

- **`controllers`:** contains all [Spring Boot REST controllers](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html).

- **`entities`:** contains all the [JPA entity mappings](https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html).

- **`dtos`:** contains all the [data transfer object (DTO)](https://en.wikipedia.org/wiki/Data_transfer_object) data classes.

- **`repositories`:** contains all [JPA repositories](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories).

To begin building the demo application, configure your H2 database instance. Add the following lines to the `application.properties` Spring Boot file:

```yaml
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
```

`spring.jpa.hibernate.ddl-auto=create-drop` causes the database to be recreated each time the Spring Boot application is launched. Considering that H2 is an in-memory database, this is exactly what you want.

Now, enter the `entities` folder and initialize the `Post.java` file with the following code:

```java
package com.influxdata.demo.entities;

import javax.persistence.*;
import java.util.Objects;

@Entity
@Table(name = "posts")
public class Post {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String url;

  private String authorEmail;

  // getters, setters, equals, and hashCode omitted for brevity
}
```

This `@Entity` class contains the post requests information and maps the `posts` H2 table that will be created automatically on startup. Keep in mind that you need to implement the omitted `getters`, `setters`, `equals`, and `hashCode` functions to make the class work. You can take a look at the full code on this [GitHub site](https://github.com/Tonel/influxdb-spring-boot-demo/blob/main/src/main/java/com/influxdata/demo/entities/Post.java).

Now, define a JPA repository for `Post`. Under the `repositories` folder, initialize the `PostRepository.java` JPA repository class as follows:

```java
package com.influxdata.demo.repositories;

import com.influxdata.demo.entities.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
```

If you're not familiar with JPA repositories, you can learn more in the official [Spring reference documentation](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories). Specifically, you need the `PostRepository` class to perform CRUD operations on `Post`.

Now it's time to configure Micrometer to automatically write data to your InfluxDB instance. You can achieve this by adding the following lines to your `application.properties` file:

```yaml
management.metrics.export.influx.bucket=${INFLUXDB_BUCKET}
management.metrics.export.influx.org=${INFLUXDB_ORG}
management.metrics.export.influx.token=${INFLUXDB_TOKEN}
management.metrics.export.influx.uri=${INFLUXDB_URI}
```

If you don't know how to define these four env files, take a look at the following description:

- **`INFLUXDB_BUCKET`:** is the name of the InfluxDB bucket (in this example, its "posts").

- **`INFLUXDB_ORG`:** is your InfluxDB `org` value. On InfluxDB Cloud, you can retrieve it at `/load-data/client-libraries/java`.

- **`INFLUXDB_TOKEN`:** is the API token you created earlier.

- **`INFLUXDB_URI`:** is the URI to the InfluxDB instance (here, it's `https://us-east-1-1.aws.cloud2.influxdata.com`).

Next, you need to use a Micrometer to log data. Following is an example of how you can use Micrometer:

```java
Counter counter = Metrics.counter(
  // metric name
  "request.posts",
  // tags
  "postId", // key
  1, // value
  "status", // key
  "draft-received" // value
);

// updating the metric in memory
// and automatically writing it to InfluxDB
counter.increment();
```

In detail, the snippet earlier will record the metric couples `<"postId", "1">` and `<"status", "draft-received">` in Micrometer.

As you can see, a Micrometer element consists of a name and a list of tags. You can initialize a Micrometer element with `Metrics.counter()`. To do so, separate each word of the metric's name with a period. This will help ensure the portability of metric names across different monitoring systems.

> Please note that `Metrics.counter()` `tags` variables follow a `key, value` approach. When `counter.increment()` is executed, the metrics data will be automatically transferred to InfluxDB behind the scenes.

You can configure Spring Boot to expose Micrometer metrics via the Actuator web endpoints with the following `application.properties` configurations:

```yaml
management.endpoint.metrics.enabled=true
management.endpoints.web.exposure.include=*
management.endpoint.beans.enabled=true
```

If you're not familiar with the Spring Boot Actuator web endpoints, you can learn more in [this official documentation](https://docs.spring.io/spring-boot/docs/2.7.3/actuator-api/htmlsingle/).

Then you can access the `request.posts` Actuator endpoint with the following URL:

```
http://localhost:8080/actuator/metrics/request.posts
```

This will return the following:

```json
{
  "name": "request.posts",
  "description": null,
  "baseUnit": null,
  "measurements": [
    {
      "statistic": "COUNT",
      "value": 0
    }
  ],
  "availableTags": [
    {
      "tag": "postId",
      "values": [
        "1"
      ]
    },
    {
      "tag": "status",
      "values": [
        "draft-received"
      ]
    }
  ]
}
```

Now, you need to initialize a `PostRequest` DTO class. Enter the `dtos` package and create a `PostRequest.java` file like this:

```java
package com.influxdata.demo.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;

public class PostRequest {
  @JsonProperty("url")
  private String url;

  @JsonProperty("authorEmail")
  private String authorEmail;

  public PostRequest() {}

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  public String getAuthorEmail() {
    return authorEmail;
  }

  public void setAuthorEmail(String authorEmail) {
    this.authorEmail = authorEmail;
  }
}
```

This class will be used by the following `PostController` to map the data received from the users in the POST and PUT requests.

Now, you're ready to define a simple `PostController` class exposing basic CRUD API logging data to InfluxDB with Micrometer. Enter the `controllers` folder and create a `PostController.java` file as follows:

```java
package com.influxdata.demo.controllers;

import com.influxdata.demo.dtos.PostRequest;
import com.influxdata.demo.entities.Post;
import com.influxdata.demo.repositories.PostRepository;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("api/v1/posts")
public class PostController {

  private final PostRepository postRepository;

  PostController(@Autowired PostRepository postRepository) {
    this.postRepository = postRepository;
  }

  @GetMapping()
  public ResponseEntity <List<Post>> getAll() {
    return new ResponseEntity<> (
      postRepository.findAll(),
      HttpStatus.CREATED
    );
  }

  @PostMapping()
  public ResponseEntity <Void> create(
    @RequestBody PostRequest postRequest
  ) {
    // creation logic
    Post postToCreate = new Post();
    postToCreate.setUrl(postRequest.getUrl());
    postToCreate.setAuthorEmail(postRequest.getAuthorEmail());
    Post post = postRepository.save(postToCreate);

    // logging the initial post request status with Micrometer
    Counter counter = Metrics.counter(
      "request.posts",
      "postId",
      post.getId().toString(),
      "status",
      "draft-received"
    );

    counter.increment();

    return new ResponseEntity<>(HttpStatus.CREATED);
  }

  @PutMapping("{id}")
  public ResponseEntity < Void > update(
    @PathVariable(value = "id") Long id,
    @RequestBody PostRequest postRequest
  ) {
    // update logic
    Post postToUpdate = postRepository.findById(id).get();
    postToUpdate.setUrl(postRequest.getUrl());
    postToUpdate.setAuthorEmail(postRequest.getAuthorEmail());
    postRepository.save(postToUpdate);

    // logging the new post request status with Micrometer
    Counter counter = Metrics.counter(
      "request.posts",
      "postId",
      id.toString(),
      "status",
      "updated"
    );

    counter.increment();

    return new ResponseEntity<>(HttpStatus.OK);
  }

  @DeleteMapping("{id}")
  public ResponseEntity<Void> delete(
    @PathVariable(value = "id") Long id
  ) {
    // delete logic
    postRepository.deleteById(id);

    // logging the new post request status with Micrometer
    Counter counter = Metrics.counter(
      "request.posts",
      "postId",
      id.toString(),
      "status",
      "deleted"
    );

    counter.increment();

    return new ResponseEntity <> (HttpStatus.NO_CONTENT);
  }
}
```

Launch your Spring Boot application and start creating, updating, and deleting posts. Then visit your InfluxDB **Data Explorer** page, select the **posts** bucket, and review your metrics:

![](https://writech.run/wp-content/uploads/2023/12/image-1.gif)

> Please note that the Spring Boot Actuator library automatically defines a list of useful application metrics in Micrometer, which sends them accordingly to InfluxDB. You can learn how to enable or disable these metrics [in Spring Boot's official docs](https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/production-ready-metrics.html#production-ready-metrics-getting-started).

To view your custom log metrics, activate the **Simple Table** view, select **request\_posts** at the bottom of the screen, and turn on the **View Raw Data** option through the slider. And you should be able to see your custom log metrics:

![Customizing your metrics](https://writech.run/wp-content/uploads/2023/12/image-36.png)

Now, you've officially collected application metrics with Micrometer and stored them on InfluxDB in Spring Boot.

## Conclusion

In this article, you learned how to build a Spring Boot Java application that can collect metrics and store them automatically in InfluxDB. With a dimensional metrics collection tool like Micrometer, you can configure your Spring Boot application to collect different metrics and send them to your preferred database technology.
  
***
_The post "[How to Store Spring Boot Application Metrics in InfluxDB](https://writech.run/blog/how-to-store-spring-boot-application-metrics-in-influxdb/)" appeared first on [Writech](https://writech.run)._