[[production-ready]]
= Production-ready Features

Spring Modulith provides support to expose architectural information about your system as a Spring Boot actuator endpoint as well as observing the interaction between application modules by capturing metrics and traces.
As  a production-ready application is likely to require both, the most convenient way to activate those features is to use the Spring Modulith Insight starter as follows:

.Using the Spring Modulith Insight starter
[tabs]
======
Maven::
+
[source, xml, subs="+attributes", role="primary"]
----
<dependency>
  <groupId>org.springframework.modulith</groupId>
  <artifactId>spring-modulith-starter-insight</artifactId>
  <version>{projectVersion}</version>
  <scope>runtime</scope>
</dependency>
----

Gradle::
+
[source, subs="+attributes", role="secondary"]
----
dependencies {
  runtimeOnly 'org.springframework.modulith:spring-modulith-starter-insight:{projectVersion}'
}
----
======

This will include the actuator and observability support as well as Spring Boot's actuator startup for general support for actuators.
Note, that you will still have to add further dependencies to connect your application to your monitoring tools such as https://zipkin.io/[Zipkin], https://docs.wavefront.com/[Wavefront] etc. usually via https://opentelemetry.io/[OpenTelemetry] or https://github.com/openzipkin/brave[Brave].
Find more information on that in https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.micrometer-tracing[the corresponding section] of Spring Boot's reference documentation.

[[actuator]]
== [[observability.actuator]]Application Module Actuator

The application module structure can be exposed as Spring Boot actuator.
To enable the actuator, add the `spring-modulith-actuator` dependency to the project:

.Using the Spring Modulith actuator support
[tabs]
======
Maven::
+
[source, xml, subs="+attributes", role="primary"]
----
<dependency>
  <groupId>org.springframework.modulith</groupId>
  <artifactId>spring-modulith-actuator</artifactId>
  <version>{projectVersion}</version>
  <scope>runtime</scope>
</dependency>

<!-- Spring Boot actuator starter required to enable actuators in general -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
  <version>…</version>
  <scope>runtime</scope>
</dependency>
----

Gradle::
+
[source, subs="+attributes", role="secondary"]
----
dependencies {
  runtimeOnly 'org.springframework.modulith:spring-modulith-actuator:{projectVersion}'
}

<!-- Spring Boot actuator starter required to enable actuators in general -->
dependencies {
  runtimeOnly 'org.springframework.boot:spring-boot-starter-actuator'
}
----
======

Running the application will now expose an `modulith` actuator resource:

.Accessing the actuator HTTP resource
[source, json]
----
GET http://localhost:8080/actuator

{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "health-path": {
      "href": "http://localhost:8080/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://localhost:8080/actuator/health",
      "templated": false
    },
    "modulith": { <1>
      "href": "http://localhost:8080/actuator/modulith",
      "templated": false
    }
  }
}
----
<1> The `modulith` actuator resource advertised.

The `modulith` resource adheres to the following structure:

.The JSON structure of the application modules actuator
[%autowidth.stretch]
|===
|JSONPath|Description

|`+$.{moduleName}+`|The technical name of an application module. Target for module references in `dependencies.target`.
|`+$.{moduleName}.displayName+`|The human-readable name of the application module.
|`+$.{moduleName}.basePackage+`|The application module's base package.
|`+$.{moduleName}.dependencies[]+`|All outgoing dependencies of the application module
|`+$.{moduleName}.dependencies[].target+`|The name of the application module depended on. A reference to a `+{moduleName}+`.
|`+$.{moduleName}.dependencies[].types[]+`|The types of dependencies towards the target module. Can either be `DEFAULT` (simple type dependency), `USES_COMPONENT` (Spring bean dependency) or `EVENT_LISTENER`.
|===

An example module arrangement would look like this:

.An example response for the application modules actuator
[source, json]
----
{
  "a": {
    "basePackage": "example.a",
    "displayName": "A",
    "dependencies": []
  },
  "b": {
    "basePackage": "example.b",
    "displayName": "B",
    "dependencies": [ {
      "target": "a",
      "types": [ "EVENT_LISTENER", "USES_COMPONENT" ]
    } ]
  }
}
----

[[observability]]
== [[observability]]Observing Application Modules
:imagesdir: images

The interaction between application modules can be intercepted to create Micrometer spans to ultimately end up in traces you can visualize in tools like https://zipkin.io/[Zipkin].
To activate the instrumentation add the following runtime dependency to your project:

.Using the Spring Modulith observability support
[tabs]
======
Maven::
+
[source, xml, subs="+attributes", role="primary"]
----
<dependency>
  <groupId>org.springframework.modulith</groupId>
  <artifactId>spring-modulith-observability</artifactId>
  <version>{projectVersion}</version>
  <scope>runtime</scope>
</dependency>
----

Gradle::
+
[source, subs="+attributes", role="secondary"]
----
dependencies {
  runtimeOnly 'org.springframework.modulith:spring-modulith-observability:{projectVersion}'
}
----
======

NOTE: You will have to configure additional infrastructure dependencies depending on the tooling you want to pipe the observability metadata in.
For details, please check the corresponding https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.micrometer-tracing[Spring Boot documentation] on which dependencies to include for your setup.

This will cause all Spring components that are part of the application module's API being decorated with an aspect that will intercept invocations and create Micrometer spans for them.
A sample invocation trace can be seen below:

.A sample module invocation trace
image::observability.png[]

In this particular case, triggering the payment changes the state of the order which then causes an order completion event being triggered.
This gets picked up asynchronously by the engine that triggers another state change on the order, works for a couple of seconds and triggers the final state change on the order in turn.
