diff --git a/Microservices/docker-compose.yml b/Microservices/docker-compose.yml new file mode 100644 index 00000000..422ae5c6 --- /dev/null +++ b/Microservices/docker-compose.yml @@ -0,0 +1,53 @@ +services: + loki: + image: grafana/loki:main + container_name: loki + command: [ "-config.file=/etc/loki/local-config.yaml" ] + ports: + - "3100:3100" + networks: + - monitoring + + prometheus: + image: prom/prometheus:v2.51.2 + container_name: prometheus + command: + - --enable-feature=exemplar-storage + - --config.file=/etc/prometheus/prometheus.yml + volumes: + - ./monitor/docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro + ports: + - "9090:9090" + networks: + - monitoring + + tempo: + image: grafana/tempo:2.2.2 + container_name: tempo + command: [ "-config.file=/etc/tempo.yaml" ] + volumes: + - ./monitor/docker/tempo/tempo.yml:/etc/tempo.yaml:ro + - ./monitor/data/tempo:/tmp/tempo + ports: + - "3110:3100" # Tempo + - "9411:9411" # zipkin + networks: + - monitoring + + grafana: + image: grafana/grafana:10.1.0 + container_name: grafana + volumes: + - ./monitor/docker/grafana:/etc/grafana/provisioning/datasources:ro + environment: + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + - GF_AUTH_DISABLE_LOGIN_FORM=true + ports: + - "3000:3000" + networks: + - monitoring + +networks: + monitoring: + driver: bridge \ No newline at end of file diff --git a/Microservices/email-service/build.gradle b/Microservices/email-service/build.gradle index c9f410ae..41bb69fb 100644 --- a/Microservices/email-service/build.gradle +++ b/Microservices/email-service/build.gradle @@ -29,11 +29,19 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-aop' + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'com.resend:resend-java:3.1.0' implementation 'org.springframework.kafka:spring-kafka:3.3.0' + implementation 'com.github.loki4j:loki-logback-appender:1.6.0' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing-bridge-brave' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.1" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' diff --git a/Microservices/email-service/src/main/java/app/sportahub/emailservice/config/ObservationConfig.java b/Microservices/email-service/src/main/java/app/sportahub/emailservice/config/ObservationConfig.java new file mode 100644 index 00000000..95cbea86 --- /dev/null +++ b/Microservices/email-service/src/main/java/app/sportahub/emailservice/config/ObservationConfig.java @@ -0,0 +1,15 @@ +package app.sportahub.emailservice.config; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObservationConfig { + + @Bean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} \ No newline at end of file diff --git a/Microservices/email-service/src/main/java/app/sportahub/emailservice/config/SecurityConfig.java b/Microservices/email-service/src/main/java/app/sportahub/emailservice/config/SecurityConfig.java new file mode 100644 index 00000000..8854f526 --- /dev/null +++ b/Microservices/email-service/src/main/java/app/sportahub/emailservice/config/SecurityConfig.java @@ -0,0 +1,40 @@ +package app.sportahub.emailservice.config; + + +import lombok.SneakyThrows; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity(prePostEnabled = true) +public class SecurityConfig { + + @Bean + public JwtAuthenticationConverter jwtAuthenticationConverter() { + return KeycloakJwtAuthenticationConverter.jwtAuthenticationConverter(); + } + + @SneakyThrows + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) { + return http + .authorizeHttpRequests(authorizeRequests -> authorizeRequests + .requestMatchers( + "/swagger-ui.html", + "/api-docs", + "/api-docs/**", + "/swagger-ui/**", + "/webjars/**", + "/actuator/**") + .permitAll() + .anyRequest().authenticated()) + .csrf(AbstractHttpConfigurer::disable) + .oauth2Login(Customizer.withDefaults()) + .oauth2ResourceServer(oauth2 -> oauth2 + .jwt(jwt -> jwt + .jwtAuthenticationConverter( + jwtAuthenticationConverter()))) + .build(); + } +} \ No newline at end of file diff --git a/Microservices/email-service/src/main/resources/application.properties b/Microservices/email-service/src/main/resources/application.properties index 34231768..ccff1e3c 100644 --- a/Microservices/email-service/src/main/resources/application.properties +++ b/Microservices/email-service/src/main/resources/application.properties @@ -1,2 +1,9 @@ spring.application.name=emailservice server.servlet.context-path=${SERVER_SERVLET_CONTEXT_PATH:/api/email-service} +server.port=8081 + +#Prometheus +management.endpoints.web.exposure.include=health, info, metrics, prometheus +management.metrics.distribution.percentiles-histogram.http.server.requests=true +management.observations.key-values.application=email-service +management.tracing.sampling.probability=1.0 diff --git a/Microservices/email-service/src/main/resources/logback-spring.xml b/Microservices/email-service/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..173923d2 --- /dev/null +++ b/Microservices/email-service/src/main/resources/logback-spring.xml @@ -0,0 +1,24 @@ + + + + + + + + http://localhost:3100/loki/api/v1/push + + + + + ${FILE_LOG_PATTERN} + + true + + + + + + + \ No newline at end of file diff --git a/Microservices/event-service/build.gradle b/Microservices/event-service/build.gradle index 3052d7ea..8702d841 100644 --- a/Microservices/event-service/build.gradle +++ b/Microservices/event-service/build.gradle @@ -33,9 +33,17 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' + implementation 'org.springframework.boot:spring-boot-starter-aop' + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' implementation 'org.mapstruct:mapstruct:1.6.2' + implementation 'com.github.loki4j:loki-logback-appender:1.6.0' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing' + implementation 'io.micrometer:micrometer-tracing-bridge-brave' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.1" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' diff --git a/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/ObservationConfig.java b/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/ObservationConfig.java new file mode 100644 index 00000000..6d9b5000 --- /dev/null +++ b/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/ObservationConfig.java @@ -0,0 +1,13 @@ +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObservationConfig { + + @Bean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} \ No newline at end of file diff --git a/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/SecurityConfig.java b/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/SecurityConfig.java index 3ab79ca5..207d6732 100644 --- a/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/SecurityConfig.java +++ b/Microservices/event-service/src/main/java/app/sportahub/eventservice/config/SecurityConfig.java @@ -33,7 +33,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) { "/api-docs", "/api-docs/**", "/swagger-ui/**", - "/webjars/**") + "/webjars/**", + "/actuator/**") .permitAll() .anyRequest().authenticated()) .csrf(AbstractHttpConfigurer::disable) diff --git a/Microservices/event-service/src/main/java/app/sportahub/eventservice/repository/EventRepository.java b/Microservices/event-service/src/main/java/app/sportahub/eventservice/repository/EventRepository.java index f320e7e3..224c1e28 100644 --- a/Microservices/event-service/src/main/java/app/sportahub/eventservice/repository/EventRepository.java +++ b/Microservices/event-service/src/main/java/app/sportahub/eventservice/repository/EventRepository.java @@ -5,10 +5,13 @@ import org.springframework.data.domain.Page; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; +import io.micrometer.observation.annotation.Observed; + import java.util.Optional; @Repository +@Observalble public interface EventRepository extends MongoRepository { Optional findEventById(String id); diff --git a/Microservices/event-service/src/main/resources/application.properties b/Microservices/event-service/src/main/resources/application.properties index 4c04efca..2a8e6007 100644 --- a/Microservices/event-service/src/main/resources/application.properties +++ b/Microservices/event-service/src/main/resources/application.properties @@ -2,6 +2,7 @@ spring.application.name=${SPRING_APPLICATION_NAME:event-service} server.servlet.context-path=${SERVER_SERVLET_CONTEXT_PATH:/api/event-service} logging.level.app.sportahub=${LOGGING_LEVEL_APP_SPORTAHUB:info} logging.level.org.springframework.web=${LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB:debug} +server.port=8082 # OAuth2 Client Configuration spring.security.oauth2.client.registration.keycloak.client-id=${KEYCLOAK_CLIENT_ID} @@ -44,3 +45,9 @@ springdoc.swagger-ui.urls[1].url=http://localhost:8080/api/event-service/api-doc # Spring Data MongoDB spring.data.mongodb.uri=${MONGODB_URI:mongodb://root:password@sporta-host:27017/event-service?authSource=admin} + +#Prometheus +management.endpoints.web.exposure.include=health, info, metrics, prometheus +management.metrics.distribution.percentiles-histogram.http.server.requests=true +management.observations.key-values.application=event-service +management.tracing.sampling.probability=1.0 \ No newline at end of file diff --git a/Microservices/event-service/src/main/resources/logback-spring.xml b/Microservices/event-service/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..173923d2 --- /dev/null +++ b/Microservices/event-service/src/main/resources/logback-spring.xml @@ -0,0 +1,24 @@ + + + + + + + + http://localhost:3100/loki/api/v1/push + + + + + ${FILE_LOG_PATTERN} + + true + + + + + + + \ No newline at end of file diff --git a/Microservices/gateway/build.gradle b/Microservices/gateway/build.gradle index 5266e976..5de058c2 100644 --- a/Microservices/gateway/build.gradle +++ b/Microservices/gateway/build.gradle @@ -7,7 +7,6 @@ plugins { group = 'app.sportahub' version = '0.0.1-SNAPSHOT' - java { toolchain { languageVersion = JavaLanguageVersion.of(21) @@ -27,10 +26,9 @@ repositories { } ext { - set('springCloudVersion', "2023.0.3") + set('springCloudVersion', "2023.0.3") } - dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-gateway-mvc' implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' @@ -38,7 +36,13 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' + implementation 'org.springframework.boot:spring-boot-starter-aop' + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.keycloak:keycloak-spring-boot-starter:24.0.4' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing-bridge-brave' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.1" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave' implementation 'org.projectlombok:lombok' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' @@ -48,14 +52,23 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'org.springframework.cloud:spring-cloud-starter-gateway-mvc' + implementation 'org.springframework.boot:spring-boot-starter-aop' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'com.github.loki4j:loki-logback-appender:1.6.0' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.6" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave:2.16.3' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } dependencyManagement { - imports { - mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" - } + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() } diff --git a/Microservices/gateway/src/main/java/app/sportahub/gateway/config/ObservationConfig.java b/Microservices/gateway/src/main/java/app/sportahub/gateway/config/ObservationConfig.java new file mode 100644 index 00000000..6d9b5000 --- /dev/null +++ b/Microservices/gateway/src/main/java/app/sportahub/gateway/config/ObservationConfig.java @@ -0,0 +1,13 @@ +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObservationConfig { + + @Bean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} \ No newline at end of file diff --git a/Microservices/gateway/src/main/java/app/sportahub/gateway/config/SecurityConfig.java b/Microservices/gateway/src/main/java/app/sportahub/gateway/config/SecurityConfig.java index 21e3535e..ee3eb478 100644 --- a/Microservices/gateway/src/main/java/app/sportahub/gateway/config/SecurityConfig.java +++ b/Microservices/gateway/src/main/java/app/sportahub/gateway/config/SecurityConfig.java @@ -23,7 +23,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) { "/api/user-service/auth/register", "/api/user-service/auth/login", "/api/user-service/auth/refresh", - "/api/user-service/auth/reset-password") + "/api/user-service/auth/reset-password", + "/actuator/**") .permitAll() .anyRequest().authenticated()) .csrf(AbstractHttpConfigurer::disable) diff --git a/Microservices/gateway/src/main/resources/application.properties b/Microservices/gateway/src/main/resources/application.properties index 2f4c93e5..e3867db0 100644 --- a/Microservices/gateway/src/main/resources/application.properties +++ b/Microservices/gateway/src/main/resources/application.properties @@ -1,5 +1,5 @@ spring.application.name=gateway - +server.port=8083 # OAuth2 Client Configuration spring.security.oauth2.client.registration.keycloak.client-id=${KEYCLOAK_CLIENT_ID} @@ -30,3 +30,9 @@ keycloak.use-resource-role-mappings = true # Admin Client Credentials for user management keycloak.admin-client-id=${KEYCLOAK_CLIENT_ID} keycloak.admin-client-secret=${KEYCLOAK_CLIENT_SECRET} + +#Prometheus +management.endpoints.web.exposure.include=health, info, metrics, prometheus +management.metrics.distribution.percentiles-histogram.http.server.requests=true +management.observations.key-values.application=gateway +management.tracing.sampling.probability=1.0 diff --git a/Microservices/gateway/src/main/resources/logback-spring.xml b/Microservices/gateway/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..173923d2 --- /dev/null +++ b/Microservices/gateway/src/main/resources/logback-spring.xml @@ -0,0 +1,24 @@ + + + + + + + + http://localhost:3100/loki/api/v1/push + + + + + ${FILE_LOG_PATTERN} + + true + + + + + + + \ No newline at end of file diff --git a/Microservices/messaging-service/build.gradle b/Microservices/messaging-service/build.gradle index 45bd33be..2a46cdd1 100644 --- a/Microservices/messaging-service/build.gradle +++ b/Microservices/messaging-service/build.gradle @@ -33,9 +33,15 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-websocket' + implementation 'org.springframework.boot:spring-boot-starter-aop' + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' implementation 'org.mapstruct:mapstruct:1.6.2' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing-bridge-brave' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.1" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' diff --git a/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/ObservationConfig.java b/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/ObservationConfig.java new file mode 100644 index 00000000..201114d7 --- /dev/null +++ b/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/ObservationConfig.java @@ -0,0 +1,15 @@ +package app.sportahub.messagingservice.config; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObservationConfig { + + @Bean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} \ No newline at end of file diff --git a/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/SecurityConfig.java b/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/SecurityConfig.java index 17d5b62a..5f3cdc7e 100644 --- a/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/SecurityConfig.java +++ b/Microservices/messaging-service/src/main/java/app/sportahub/messagingservice/config/SecurityConfig.java @@ -33,7 +33,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) { "/api-docs", "/api-docs/**", "/swagger-ui/**", - "/webjars/**") + "/webjars/**", + "/actuator/**") .permitAll() .anyRequest().authenticated()) .csrf(AbstractHttpConfigurer::disable) diff --git a/Microservices/messaging-service/src/main/resources/application.properties b/Microservices/messaging-service/src/main/resources/application.properties index 98e0bd07..9501050b 100644 --- a/Microservices/messaging-service/src/main/resources/application.properties +++ b/Microservices/messaging-service/src/main/resources/application.properties @@ -3,6 +3,8 @@ server.servlet.context-path=${SERVER_SERVLET_CONTEXT_PATH:/api/messaging-service logging.level.app.sportahub=${LOGGING_LEVEL_APP_SPORTAHUB:info} logging.level.org.springframework.web=${LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB:debug} +server.port=8084 + # OAuth2 Client Configuration spring.security.oauth2.client.registration.keycloak.client-id=${KEYCLOAK_CLIENT_ID} spring.security.oauth2.client.registration.keycloak.client-secret=${KEYCLOAK_CLIENT_SECRET} @@ -33,7 +35,6 @@ keycloak.use-resource-role-mappings = true keycloak.admin-client-id=${KEYCLOAK_CLIENT_ID} keycloak.admin-client-secret=${KEYCLOAK_CLIENT_SECRET} - # Swagger springdoc.api-docs.path=/api-docs springdoc.swagger-ui.path=/swagger-ui.html @@ -44,3 +45,10 @@ springdoc.swagger-ui.urls[1].url=http://localhost:8080/api/messaging-service/api # Spring Data MongoDB spring.data.mongodb.uri=${MONGODB_URI:mongodb://root:password@sporta-host:27017/messaging-service?authSource=admin} + +# Prometheus +management.endpoints.web.exposure.include=health, info, metrics, prometheus +management.endpoint.prometheus.access=unrestricted +management.metrics.distribution.percentiles-histogram.http.server.requests=true +management.observations.key-values.application=messaging-service +management.tracing.sampling.probability=1.0 \ No newline at end of file diff --git a/Microservices/monitor/docker/grafana/dashboard.json b/Microservices/monitor/docker/grafana/dashboard.json new file mode 100644 index 00000000..6751aead --- /dev/null +++ b/Microservices/monitor/docker/grafana/dashboard.json @@ -0,0 +1,3295 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": [], + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "8.5.2" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph (old)", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "Dashboard for Spring Boot2 Statistics(by micrometer-prometheus).", + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 6756, + "graphTooltip": 0, + "id": null, + "iteration": 1654853269928, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 54, + "panels": [], + "title": "Basic Statistics", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 1 + }, + "id": 52, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "process_uptime_seconds{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 14400, + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 70 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 6, + "y": 1 + }, + "id": 58, + "links": [], + "maxDataPoints": 100, + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})*100/sum(jvm_memory_max_bytes{application=\"$application\",instance=\"$instance\", area=\"heap\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 14400, + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Heap Used", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + }, + { + "options": { + "from": -1e+32, + "result": { + "text": "N/A" + }, + "to": 0 + }, + "type": "range" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 70 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 11, + "y": 1 + }, + "id": 60, + "links": [], + "maxDataPoints": 100, + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})*100/sum(jvm_memory_max_bytes{application=\"$application\",instance=\"$instance\", area=\"nonheap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 14400, + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Non-Heap Used", + "type": "gauge" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 1 + }, + "hiddenSeries": false, + "id": 66, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_files_open{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Open Files", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "process_files_max{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Max Files", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Process Open Files", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "locale", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "dateTimeAsIso" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 4 + }, + "id": 56, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "process_start_time_seconds{application=\"$application\", instance=\"$instance\"}*1000", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 14400, + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Start time", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 95, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "system_cpu_usage{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "System CPU Usage", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "process_cpu_usage{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Process CPU Usage", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "hiddenSeries": false, + "id": 96, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "system_load_average_1m{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Load Average [1m]", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "system_cpu_count{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "CPU Core Size", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Load Average", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 48, + "panels": [], + "title": "JVM Statistics - Memory", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 85, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "memory_pool_heap", + "repeatDirection": "h", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{instance=\"$instance\", application=\"$application\", id=\"$memory_pool_heap\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Used", + "refId": "C", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_memory_committed_bytes{instance=\"$instance\", application=\"$application\", id=\"$memory_pool_heap\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Commited", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_memory_max_bytes{instance=\"$instance\", application=\"$application\", id=\"$memory_pool_heap\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Max", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "$memory_pool_heap (heap)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 23 + }, + "hiddenSeries": false, + "id": 88, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "memory_pool_nonheap", + "repeatDirection": "h", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{instance=\"$instance\", application=\"$application\", id=\"$memory_pool_nonheap\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Used", + "refId": "C", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_memory_committed_bytes{instance=\"$instance\", application=\"$application\", id=\"$memory_pool_nonheap\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Commited", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_memory_max_bytes{instance=\"$instance\", application=\"$application\", id=\"$memory_pool_nonheap\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Max", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "$memory_pool_nonheap (non-heap)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 23 + }, + "hiddenSeries": false, + "id": 80, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(jvm_classes_unloaded_total{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Classes Unloaded", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Classes Unloaded", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "decimals": 0, + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 39 + }, + "id": 50, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_classes_loaded{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Classes Loaded", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Classes Loaded", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "locale", + "label": "", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 39 + }, + "hiddenSeries": false, + "id": 83, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.5.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_buffer_memory_used_bytes{instance=\"$instance\", application=\"$application\", id=\"mapped\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Used Bytes", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_buffer_total_capacity_bytes{instance=\"$instance\", application=\"$application\", id=\"mapped\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Capacity Bytes", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Mapped Buffers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 46 + }, + "id": 78, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(jvm_gc_memory_allocated_bytes_total{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "allocated", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "irate(jvm_gc_memory_promoted_bytes_total{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "promoted", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Memory Allocate/Promote", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 47 + }, + "id": 82, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_buffer_memory_used_bytes{instance=\"$instance\", application=\"$application\", id=\"direct\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Used Bytes", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_buffer_total_capacity_bytes{instance=\"$instance\", application=\"$application\", id=\"direct\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Capacity Bytes", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Direct Buffers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 54 + }, + "id": 68, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_threads_daemon{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Daemon", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_threads_live{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Live", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "jvm_threads_peak{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Peak", + "refId": "C", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Threads", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 62 + }, + "id": 72, + "panels": [], + "title": "JVM Statistics - GC", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 63 + }, + "id": 74, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(jvm_gc_pause_seconds_count{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{action}} [{{cause}}]", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "GC Count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "locale", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 63 + }, + "id": 76, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(jvm_gc_pause_seconds_sum{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{action}} [{{cause}}]", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "GC Stop the World Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 73 + }, + "id": 34, + "panels": [], + "title": "HikariCP Statistics", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 74 + }, + "id": 44, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "hikaricp_connections{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Connections Size", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 8, + "w": 20, + "x": 4, + "y": 74 + }, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": false, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "hikaricp_connections_active{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Active", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "hikaricp_connections_idle{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Idle", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "hikaricp_connections_pending{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Pending", + "refId": "C", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 78 + }, + "id": 46, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "hikaricp_connections_timeout_total{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Connection Timeout Count", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 82 + }, + "id": 38, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "hikaricp_connections_creation_seconds_sum{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"} / hikaricp_connections_creation_seconds_count{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Creation Time", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Connection Creation Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 82 + }, + "id": 42, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "hikaricp_connections_usage_seconds_sum{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"} / hikaricp_connections_usage_seconds_count{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Usage Time", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Connection Usage Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 82 + }, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "hikaricp_connections_acquire_seconds_sum{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"} / hikaricp_connections_acquire_seconds_count{instance=\"$instance\", application=\"$application\", pool=\"$hikaricp\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Acquire Time", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Connection Acquire Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 88 + }, + "id": 18, + "panels": [], + "title": "HTTP Statistics", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 89 + }, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(http_server_requests_seconds_count{instance=\"$instance\", application=\"$application\", uri!~\".*actuator.*\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{method}} [{{status}}] - {{uri}}", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Request Count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 96 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(http_server_requests_seconds_sum{instance=\"$instance\", application=\"$application\", exception=\"None\", uri!~\".*actuator.*\"}[5m]) / irate(http_server_requests_seconds_count{instance=\"$instance\", application=\"$application\", exception=\"None\", uri!~\".*actuator.*\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{method}} [{{status}}] - {{uri}}", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Response Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 103 + }, + "id": 22, + "panels": [], + "title": "Tomcat Statistics", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "locale" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 104 + }, + "id": 28, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "tomcat_global_error_total{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Total Error Count", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "decimals": 0, + "fill": 1, + "gridPos": { + "h": 7, + "w": 9, + "x": 4, + "y": 104 + }, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "tomcat_sessions_active_current{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "active sessions", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Active Sessions", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 11, + "x": 13, + "y": 104 + }, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(tomcat_global_sent_bytes_total{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Sent Bytes", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "irate(tomcat_global_received_bytes_total{instance=\"$instance\", application=\"$application\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Recieved Bytes", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Sent & Recieved Bytes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "locale" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 108 + }, + "id": 32, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.5.2", + "targets": [ + { + "expr": "tomcat_threads_config_max{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "title": "Thread Config Max", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 13, + "x": 0, + "y": 111 + }, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "tomcat_threads_current{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Current thread", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + }, + { + "expr": "tomcat_threads_busy{instance=\"$instance\", application=\"$application\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Current thread busy", + "refId": "B", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "Threads", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "DxTyMDjnk" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 118 + }, + "id": 8, + "panels": [], + "title": "Logback Statistics", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 119 + }, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "expr": "irate(logback_events_total{instance=\"$instance\", application=\"$application\", level=\"info\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "info", + "rawSql": "SELECT\n $__time(time_column),\n value1\nFROM\n metric_table\nWHERE\n $__timeFilter(time_column)\n", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "INFO logs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 119 + }, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "expr": "irate(logback_events_total{instance=\"$instance\", application=\"$application\", level=\"error\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "error", + "rawSql": "SELECT\n $__time(time_column),\n value1\nFROM\n metric_table\nWHERE\n $__timeFilter(time_column)\n", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "ERROR logs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 126 + }, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "expr": "irate(logback_events_total{instance=\"$instance\", application=\"$application\", level=\"warn\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "warn", + "rawSql": "SELECT\n $__time(time_column),\n value1\nFROM\n metric_table\nWHERE\n $__timeFilter(time_column)\n", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "WARN logs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 126 + }, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "expr": "irate(logback_events_total{instance=\"$instance\", application=\"$application\", level=\"debug\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "debug", + "rawSql": "SELECT\n $__time(time_column),\n value1\nFROM\n metric_table\nWHERE\n $__timeFilter(time_column)\n", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "DEBUG logs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 126 + }, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "expr": "irate(logback_events_total{instance=\"$instance\", application=\"$application\", level=\"trace\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "trace", + "rawSql": "SELECT\n $__time(time_column),\n value1\nFROM\n metric_table\nWHERE\n $__timeFilter(time_column)\n", + "refId": "A", + "datasource": "${DS_PROMETHEUS}" + } + ], + "thresholds": [], + "title": "TRACE logs", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "refresh": "5s", + "schemaVersion": 36, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(jvm_classes_loaded_classes, instance)", + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "query": "label_values(jvm_classes_loaded_classes, instance)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(jvm_classes_loaded_classes{instance=\"$instance\"}, application)", + "hide": 0, + "includeAll": false, + "label": "Application", + "multi": false, + "name": "application", + "options": [], + "query": { + "query": "label_values(jvm_classes_loaded_classes{instance=\"$instance\"}, application)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(hikaricp_connections{instance=\"$instance\", application=\"$application\"}, pool)", + "hide": 0, + "includeAll": false, + "label": "HikariCP-Pool", + "multi": false, + "name": "hikaricp", + "options": [], + "query": { + "query": "label_values(hikaricp_connections{instance=\"$instance\", application=\"$application\"}, pool)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Memory Pool (heap)", + "multi": false, + "name": "memory_pool_heap", + "options": [], + "query": { + "query": "label_values(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"},id)", + "refId": "Prometheus-memory_pool_heap-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Memory Pool (nonheap)", + "multi": false, + "name": "memory_pool_nonheap", + "options": [], + "query": { + "query": "label_values(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"},id)", + "refId": "Prometheus-memory_pool_nonheap-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Spring Boot Statistics", + "uid": "sOae4vCnk", + "version": 3, + "weekStart": "" +} \ No newline at end of file diff --git a/Microservices/monitor/docker/grafana/datasource.yml b/Microservices/monitor/docker/grafana/datasource.yml new file mode 100644 index 00000000..3b9b4bbe --- /dev/null +++ b/Microservices/monitor/docker/grafana/datasource.yml @@ -0,0 +1,47 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + editable: false + jsonData: + httpMethod: POST + exemplarTraceIdDestinations: + - name: trace_id + datasourceUid: tempo + - name: Tempo + type: tempo + access: proxy + orgId: 1 + url: http://tempo:3200 + basicAuth: false + isDefault: true + version: 1 + editable: false + apiVersion: 1 + uid: tempo + jsonData: + httpMethod: GET + tracesToLogs: + datasourceUid: 'loki' + nodeGraph: + enabled: true + - name: Loki + type: loki + uid: loki + access: proxy + orgId: 1 + url: http://loki:3100 + basicAuth: false + isDefault: false + version: 1 + editable: false + apiVersion: 1 + jsonData: + derivedFields: + - datasourceUid: tempo + matcherRegex: \[.+,(.+?), + name: TraceID + url: $${__value.raw} \ No newline at end of file diff --git a/Microservices/monitor/docker/prometheus/prometheus.yml b/Microservices/monitor/docker/prometheus/prometheus.yml new file mode 100644 index 00000000..79fe5d0f --- /dev/null +++ b/Microservices/monitor/docker/prometheus/prometheus.yml @@ -0,0 +1,38 @@ +global: + scrape_interval: 15s + +scrape_configs: + - job_name: 'user-service' + metrics_path: '/api/user-service/actuator/prometheus' + static_configs: + - targets: [ 'host.docker.internal:8080' ] #host.docker.internal may not work on all machines. Add internal port number manually. + - job_name: 'email-service' + metrics_path: '/api/event-service/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: [ 'host.docker.internal:8081' ] + - job_name: 'event-service' + metrics_path: '/api/event-service/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: [ 'host.docker.internal:8082' ] + - job_name: 'gateway' + metrics_path: '/api/storage-service/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: [ 'host.docker.internal:8083' ] + - job_name: 'storage-service' + metrics_path: '/api/storage-service/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: [ 'host.docker.internal:8085' ] + - job_name: 'orchestration-service' + metrics_path: '/api/orchestration-service/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: [ 'host.docker.internal:8086' ] + - job_name: 'messaging-service' + metrics_path: '/api/messaging-service/actuator/prometheus' + scrape_interval: 5s + static_configs: + - targets: [ 'host.docker.internal:8084' ] \ No newline at end of file diff --git a/Microservices/monitor/docker/tempo/tempo.yml b/Microservices/monitor/docker/tempo/tempo.yml new file mode 100644 index 00000000..27b48191 --- /dev/null +++ b/Microservices/monitor/docker/tempo/tempo.yml @@ -0,0 +1,12 @@ +server: + http_listen_port: 3200 + +distributor: + receivers: + zipkin: + +storage: + trace: + backend: local + local: + path: /tmp/tempo/blocks \ No newline at end of file diff --git a/Microservices/storage-service/build.gradle b/Microservices/storage-service/build.gradle index 28218b71..98a8d374 100644 --- a/Microservices/storage-service/build.gradle +++ b/Microservices/storage-service/build.gradle @@ -31,12 +31,17 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' + implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springdoc:springdoc-openapi-starter-webflux-ui:2.3.0' implementation 'io.netty:netty-resolver-dns-native-macos:4.1.114.Final:osx-aarch_64' implementation 'org.keycloak:keycloak-spring-boot-starter:24.0.4' implementation 'org.mapstruct:mapstruct:1.6.2' implementation 'org.springframework.kafka:spring-kafka:3.3.0' implementation 'io.minio:minio:8.3.4' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing-bridge-brave' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.1" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' diff --git a/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/auth/SecurityConfig.java b/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/auth/SecurityConfig.java index ddcc8606..1459a95d 100644 --- a/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/auth/SecurityConfig.java +++ b/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/auth/SecurityConfig.java @@ -33,7 +33,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) { "/api-docs/**", "/swagger-ui/**", "/webjars/**", - "/actuator/health/**") + "/actuator/**") .permitAll() .anyRequest().authenticated()) .csrf(AbstractHttpConfigurer::disable) diff --git a/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/observability/ObservationConfig.java b/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/observability/ObservationConfig.java new file mode 100644 index 00000000..de3b96dc --- /dev/null +++ b/Microservices/storage-service/src/main/java/app/sportahub/storageservice/config/observability/ObservationConfig.java @@ -0,0 +1,15 @@ +package app.sportahub.storageservice.config.observability; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObservationConfig { + + @Bean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} diff --git a/Microservices/storage-service/src/main/resources/application.properties b/Microservices/storage-service/src/main/resources/application.properties index 38378f0a..589e42a0 100644 --- a/Microservices/storage-service/src/main/resources/application.properties +++ b/Microservices/storage-service/src/main/resources/application.properties @@ -54,3 +54,12 @@ minio.access.name=${MINIO_CLIENT_ID} minio.access.secret=${MINIO_CLIENT_SECRET} minio.url=${MINIO_URL} minio.bucket.name=${MINIO_BUCKET} + +# Prometheus +management.endpoints.web.exposure.include=health, info, metrics, prometheus +management.endpoint.prometheus.access=unrestricted +management.metrics.distribution.percentiles-histogram.http.server.requests=true +management.observations.key-values.application=storage-service +management.tracing.sampling.probability=1.0 + +server.port=8085 \ No newline at end of file diff --git a/Microservices/user-service/build.gradle b/Microservices/user-service/build.gradle index d0782038..bb5d8280 100644 --- a/Microservices/user-service/build.gradle +++ b/Microservices/user-service/build.gradle @@ -28,6 +28,7 @@ repositories { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' @@ -35,11 +36,17 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-webflux' + implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' implementation 'io.netty:netty-resolver-dns-native-macos:4.1.114.Final:osx-aarch_64' implementation 'org.keycloak:keycloak-spring-boot-starter:24.0.4' implementation 'org.mapstruct:mapstruct:1.6.2' implementation 'org.springframework.kafka:spring-kafka:3.3.0' + implementation 'com.github.loki4j:loki-logback-appender:1.3.2' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing-bridge-brave' + implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:1.0.1" + implementation 'io.zipkin.reporter2:zipkin-reporter-brave' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' diff --git a/Microservices/user-service/src/main/java/app/sportahub/userservice/config/ObservationConfig.java b/Microservices/user-service/src/main/java/app/sportahub/userservice/config/ObservationConfig.java new file mode 100644 index 00000000..a575ad90 --- /dev/null +++ b/Microservices/user-service/src/main/java/app/sportahub/userservice/config/ObservationConfig.java @@ -0,0 +1,15 @@ +package app.sportahub.userservice.config; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObservationConfig { + + @Bean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} diff --git a/Microservices/user-service/src/main/java/app/sportahub/userservice/config/auth/SecurityConfig.java b/Microservices/user-service/src/main/java/app/sportahub/userservice/config/auth/SecurityConfig.java index df872af2..f1fd55b4 100644 --- a/Microservices/user-service/src/main/java/app/sportahub/userservice/config/auth/SecurityConfig.java +++ b/Microservices/user-service/src/main/java/app/sportahub/userservice/config/auth/SecurityConfig.java @@ -28,7 +28,6 @@ public JwtAuthenticationConverter jwtAuthenticationConverter() { public SecurityFilterChain securityFilterChain(HttpSecurity http) { return http .authorizeHttpRequests(authorizeRequests -> authorizeRequests - .requestMatchers( "/auth/register", "/auth/login", @@ -38,9 +37,11 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) { "/api-docs", "/api-docs/**", "/swagger-ui/**", - "/webjars/**") - .permitAll() - .anyRequest().authenticated()) + "/webjars/**", + "/actuator/**" + ).permitAll() + .anyRequest().authenticated() + ) .csrf(AbstractHttpConfigurer::disable) .oauth2Login(Customizer.withDefaults()) .oauth2ResourceServer(oauth2 -> oauth2 diff --git a/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/BadgeRepository.java b/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/BadgeRepository.java index 760ee9b5..c9618639 100644 --- a/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/BadgeRepository.java +++ b/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/BadgeRepository.java @@ -1,9 +1,11 @@ package app.sportahub.userservice.repository; import app.sportahub.userservice.model.user.Badge; +import io.micrometer.observation.annotation.Observed; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; @Repository +@Observed public interface BadgeRepository extends MongoRepository { } diff --git a/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/SearchingUserRepository.java b/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/SearchingUserRepository.java index ff682e1a..341405dc 100644 --- a/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/SearchingUserRepository.java +++ b/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/SearchingUserRepository.java @@ -1,11 +1,13 @@ package app.sportahub.userservice.repository.user; import app.sportahub.userservice.model.user.User; +import io.micrometer.observation.annotation.Observed; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import java.util.List; +@Observed public interface SearchingUserRepository { Page searchUsers(String firstName, String lastName, List sports, List rankings, String gender, String age, Pageable pageable); } diff --git a/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/UserRepository.java b/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/UserRepository.java index 2665e27d..8819f6c9 100644 --- a/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/UserRepository.java +++ b/Microservices/user-service/src/main/java/app/sportahub/userservice/repository/user/UserRepository.java @@ -1,12 +1,14 @@ package app.sportahub.userservice.repository.user; import app.sportahub.userservice.model.user.User; +import io.micrometer.observation.annotation.Observed; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; import java.util.Optional; @Repository +@Observed public interface UserRepository extends MongoRepository, SearchingUserRepository { Optional findUserById(String id); diff --git a/Microservices/user-service/src/main/resources/application.properties b/Microservices/user-service/src/main/resources/application.properties index bc5be8e3..d9a63b23 100644 --- a/Microservices/user-service/src/main/resources/application.properties +++ b/Microservices/user-service/src/main/resources/application.properties @@ -44,9 +44,14 @@ keycloak.admin-client-secret=${KEYCLOAK_CLIENT_SECRET} # Spring Data MongoDB spring.data.mongodb.uri=${MONGODB_URI:mongodb://root:password@sporta-dev:27017/user-service?authSource=admin} -#Kafka +# Kafka spring.kafka.bootstrap-servers=localhost:9092 spring.kafka.template.default-topic=email-sent spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer +#Prometheus +management.endpoints.web.exposure.include=health, info, metrics, prometheus +management.metrics.distribution.percentiles-histogram.http.server.requests=true +management.observations.key-values.application=user-service +management.tracing.sampling.probability=1.0 diff --git a/Microservices/user-service/src/main/resources/logback-spring.xml b/Microservices/user-service/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..173923d2 --- /dev/null +++ b/Microservices/user-service/src/main/resources/logback-spring.xml @@ -0,0 +1,24 @@ + + + + + + + + http://localhost:3100/loki/api/v1/push + + + + + ${FILE_LOG_PATTERN} + + true + + + + + + + \ No newline at end of file diff --git a/docker/grafana/datasources.yml b/docker/grafana/datasources.yml new file mode 100644 index 00000000..361a01c6 --- /dev/null +++ b/docker/grafana/datasources.yml @@ -0,0 +1,47 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + editable: false + jsonData: + httpMethod: POST + exemplarTraceIdDestinations: + - name: trace_id + datasourceUid: tempo + - name: Tempo + type: tempo + access: proxy + orgId: 1 + url: http://tempo:3200 + basicAuth: false + isDefault: true + version: 1 + editable: false + apiVersion: 1 + uid: tempo + jsonData: + httpMethod: GET + tracesToLogs: + datasourceUid: 'loki' + nodeGraph: + enabled: true + - name: Loki + type: loki + uid: loki + access: proxy + orgId: 1 + url: http://loki:3100 + basicAuth: false + isDefault: false + version: 1 + editable: false + apiVersion: 1 + jsonData: + derivedFields: + - datasourceUid: tempo + matcherRegex: \[.+,(.+?), + name: TraceID + url: $${__value.raw} \ No newline at end of file diff --git a/docker/prometheus/prometheus.yml b/docker/prometheus/prometheus.yml new file mode 100644 index 00000000..3fa30853 --- /dev/null +++ b/docker/prometheus/prometheus.yml @@ -0,0 +1,12 @@ +global: + scrape_interval: 5s + evaluation_interval: 5s + +scrape_configs: + - job_name: 'prometheus' + static_configs: + - targets: ['prometheus:9090'] + - job_name: 'user-service' + metrics_path: '/actuator/prometheus' + static_configs: + - targets: ['host.docker.internal:8080'] ## only for demo purposes don't use host.docker.internal in production \ No newline at end of file diff --git a/docker/tempo/tempo.yml b/docker/tempo/tempo.yml new file mode 100644 index 00000000..27b48191 --- /dev/null +++ b/docker/tempo/tempo.yml @@ -0,0 +1,12 @@ +server: + http_listen_port: 3200 + +distributor: + receivers: + zipkin: + +storage: + trace: + backend: local + local: + path: /tmp/tempo/blocks \ No newline at end of file