Tutorial
The monolith-domain-splitter
library is designed to help you organize and monitor different domains within your
monolithic application using Datadog. This guide will help you integrate the library into your project.
Note: This project requires the Datadog agent to be configured for full functionality. While adding domain and team annotations to logs may work without Datadog, it has not been tested in such scenarios.
Step-by-Step Approach to Using Domain Annotations
1. Define Domains and Teams
You will use enums to represent different domains and teams within your application. The library will help you tag and monitor these domains effectively.
enum class DomainValueImpl(
override val team: Team,
) : DomainValue {
PROJECT(TeamImpl.LIONS),
FILE(TeamImpl.SNAILS),
}
enum class TeamImpl : Team {
LIONS,
SNAILS,
}
2. Add Dependencies
Add the library and opentracing dependencies.
If you use gradle add to your build.gradle.kts
file:
dependencies {
api("io.opentracing:opentracing-api:0.33.0")
api("io.opentracing:opentracing-util:0.33.0")
implementation("io.github.feddena.monolith.splitter:monolith-domain-splitter:0.0.2")
}
3. Annotate Your Application Class
Annotate your main application class to include the monolith-domain-splitter package for component scanning.
package your.app.pkg
@SpringBootApplication(scanBasePackages = ["your.app.pkg", "io.github.feddena.monolith.splitter"])
class StorageApplication
fun main(args: Array<String>) {
runApplication<StorageApplication>(*args)
}
4. Annotate Your Classes and Methods
Use the @Domain annotation to mark your classes and methods with specific domains.
@Domain("FILE")
class FileEndpoint {
// Your endpoint logic
}
5. Handle Unsupported Cases
For cases that cannot be annotated directly, use DomainTagsService to wrap the logic.
fun executeNotSupportedByAnnotationsLogic() {
domainTagsService.invoke(domain) { executeLogic() }
}
6. Register your custom domains to registry
@Configuration
@EnableAspectJAutoProxy
class DomainConfiguration(
private val domainRegistry: DomainRegistry,
) {
init {
DomainValueImpl.entries
.forEach { domainRegistry.registerDomainValue(it) }
}
}
7. Add DomainTraceInterceptorConfiguration to configure artificial services usage
@Configuration
class DomainTraceInterceptorConfigurationImpl : DomainTraceInterceptorConfiguration {
// name of the service in datadog if you wish to override it
override fun getServicesToOverride(): Set<String> {
return setOf("real-service-to-override")
}
// prefix that will be used to create artificial services names
// artificialServiceName = getServiceNamePrefix() + team
override fun getServiceNamePrefix(): String {
return "monolith-"
}
}
8. Add WebMvc Interceptor to support annotations on REST requests
@Component
class WebMvcConfigurerDomain(
private val domainHandlerInterceptor: DomainHandlerInterceptor,
) : WebMvcConfigurer {
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(domainHandlerInterceptor)
}
}
9. Monitor with Datadog
Use artificial service filters for monitors, dashboards, and APM traces filtering in Datadog to keep track of different domains and teams. Make sure your project has the Datadog agent configured for full functionality.
By following these steps, you can integrate and use the monolith-domain-splitter library in your project to achieve improved domain monitoring and management using Datadog. This setup ensures that each domain in your monolithic application is well-organized and tracked for better observability and accountability.