feat: vereinheitliche Startup-Logs in allen Backend-Services, verbessere Konsistenz und Diagnosemöglichkeiten

Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
Stefan Mogeritsch 2026-04-16 18:47:32 +02:00
parent 8f45544fe1
commit 0426d4ee9a
12 changed files with 275 additions and 24 deletions

View File

@ -1,25 +1,30 @@
package at.mocode.infrastructure.gateway
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.getBean
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
@SpringBootApplication
class GatewayApplication
class GatewayApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(GatewayApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8081")
val appName = env.getProperty("spring.application.name", "gateway")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
val context = runApplication<GatewayApplication>(*args)
val logger = LoggerFactory.getLogger(GatewayApplication::class.java)
val env = context.getBean<Environment>()
val port = env.getProperty("server.port") ?: "8081"
logger.info("""
----------------------------------------------------------
Application 'Gateway' is running!
Port: $port
Profiles: ${env.activeProfiles.joinToString(", ").ifEmpty { "default" }}
----------------------------------------------------------
""".trimIndent())
runApplication<GatewayApplication>(*args)
}

View File

@ -2,14 +2,33 @@
package at.mocode.billing.service
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
import kotlin.uuid.ExperimentalUuidApi
@EnableDiscoveryClient
@SpringBootApplication
class BillingServiceApplication
class BillingServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(BillingServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8087")
val appName = env.getProperty("spring.application.name", "billing-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<BillingServiceApplication>(*args)

View File

@ -1,9 +1,13 @@
package at.mocode.entries.service
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.EnableAspectJAutoProxy
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@ -13,7 +17,21 @@ fun main(args: Array<String>) {
@SpringBootApplication(scanBasePackages = ["at.mocode.entries", "at.mocode.billing", "at.mocode.infrastructure.security"])
@EnableAspectJAutoProxy
class EntriesServiceApplication {
class EntriesServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(EntriesServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8084")
val appName = env.getProperty("spring.application.name", "entries-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
@Bean
fun corsConfigurer(): WebMvcConfigurer {

View File

@ -1,8 +1,12 @@
package at.mocode.events.service
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
/**
* Main application class for the Events Service.
@ -11,7 +15,22 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient
*/
@SpringBootApplication
@EnableDiscoveryClient
class EventsServiceApplication
class EventsServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(EventsServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8085")
val appName = env.getProperty("spring.application.name", "events-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
/**
* Main entry point for the Events Service application.

View File

@ -1,10 +1,29 @@
package at.mocode.identity.service
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
@SpringBootApplication(scanBasePackages = ["at.mocode.identity", "at.mocode.infrastructure.security", "at.mocode.backend.infrastructure.persistence"])
class IdentityServiceApplication
class IdentityServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(IdentityServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8089")
val appName = env.getProperty("spring.application.name", "identity-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<IdentityServiceApplication>(*args)

View File

@ -1,10 +1,29 @@
package at.mocode.mail.service
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
@SpringBootApplication
class MailServiceApplication
class MailServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(MailServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8083")
val appName = env.getProperty("spring.application.name", "mail-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<MailServiceApplication>(*args)

View File

@ -1,15 +1,34 @@
package at.mocode.ping
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.EnableAspectJAutoProxy
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
@SpringBootApplication
@EnableAspectJAutoProxy
// Scannt das eigene Service-Package UND das Security-Infrastruktur-Package
@ComponentScan(basePackages = ["at.mocode.ping", "at.mocode.infrastructure.security"])
class PingServiceApplication
class PingServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(PingServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8082")
val appName = env.getProperty("spring.application.name", "ping-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<PingServiceApplication>(*args)

View File

@ -2,14 +2,33 @@ package at.mocode.results.service
import at.mocode.results.service.application.ResultsService
import at.mocode.results.service.domain.Ergebnis
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
import org.springframework.web.bind.annotation.*
@SpringBootApplication
@EnableDiscoveryClient
class ResultsServiceApplication
class ResultsServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(ResultsServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8088")
val appName = env.getProperty("spring.application.name", "results-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<ResultsServiceApplication>(*args)

View File

@ -1,12 +1,31 @@
package at.mocode.scheduling.service
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@SpringBootApplication
class SchedulingServiceApplication
class SchedulingServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(SchedulingServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8089")
val appName = env.getProperty("spring.application.name", "scheduling-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<SchedulingServiceApplication>(*args)

View File

@ -3,14 +3,33 @@ package at.mocode.series.service
import at.mocode.series.service.application.SeriesService
import at.mocode.series.service.domain.Serie
import at.mocode.series.service.domain.SeriePunkt
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
import org.springframework.web.bind.annotation.*
@SpringBootApplication
@EnableDiscoveryClient
class SeriesServiceApplication
class SeriesServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(SeriesServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8089")
val appName = env.getProperty("spring.application.name", "series-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
}
fun main(args: Array<String>) {
runApplication<SeriesServiceApplication>(*args)

View File

@ -2,12 +2,30 @@ package at.mocode.zns.import.service
import at.mocode.masterdata.domain.repository.*
import at.mocode.zns.importer.ZnsImportService
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
@SpringBootApplication
class ZnsImportServiceApplication {
class ZnsImportServiceApplication(private val env: Environment) {
private val log = LoggerFactory.getLogger(ZnsImportServiceApplication::class.java)
@EventListener(ApplicationReadyEvent::class)
fun onApplicationReady() {
val springPort = env.getProperty("server.port", "8095")
val appName = env.getProperty("spring.application.name", "zns-import-service")
log.info("----------------------------------------------------------")
log.info("Application '{}' is running!", appName)
log.info("Spring Management Port: {}", springPort)
log.info("Profiles: {}", env.activeProfiles.joinToString(", "))
log.info("----------------------------------------------------------")
}
@Bean
fun znsImportService(

View File

@ -0,0 +1,58 @@
# 📓 Journal-Eintrag: 2026-04-16 - Vereinheitlichung der Service-Start-Logs
## 🏗️ Status Quo
Nach dem Vorbild des `masterdata-service` sollten alle Backend-Services konsistente Informationen beim Start in die
Konsole loggen.
## 🚀 Umgesetzte Änderungen
### 1. onApplicationReady() Implementierung
In allen 11 Backend-Services wurde die Methode `onApplicationReady()` in der jeweiligen Application-Klasse
implementiert. Diese reagiert auf das `ApplicationReadyEvent` von Spring Boot.
**Betroffene Services:**
- `api-gateway`
- `masterdata-service` (bereits vorhanden)
- `events-service`
- `zns-import-service`
- `ping-service`
- `billing-service`
- `entries-service`
- `identity-service`
- `mail-service`
- `results-service`
- `scheduling-service`
- `series-service`
### 2. Standardisiertes Log-Format
Das Log-Format wurde vereinheitlicht und gibt nun folgende Informationen aus:
- Anwendungsname (aus `spring.application.name`)
- Spring Management Port (Actuator)
- Ktor API Port (falls zutreffend, z.B. bei `masterdata-service`)
- Aktive Spring-Profile
**Beispiel:**
```
----------------------------------------------------------
Application 'events-service' is running!
Spring Management Port: 8085
Profiles: docker
----------------------------------------------------------
```
## 🛠️ Technische Details
- Verwendung von `@EventListener(ApplicationReadyEvent::class)` für den exakten Zeitpunkt, wenn die App bereit ist.
- Dynamisches Auslesen der Ports und Profile über das `Environment` Objekt.
- Bereinigung der `main`-Funktion im API Gateway zugunsten des deklarativen `@EventListener` Ansatzes.
---
**🧹 [Curator]**: Start-Logs über alle Backend-Services hinweg konsolidiert.
**👷 [Backend Developer]**: Alle Application-Klassen konsistent refactored.
**🏗️ [Lead Architect]**: Observability und Diagnosemöglichkeiten beim Systemstart verbessert.