Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-214: [feat] Setup Observability For Microservices #356

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d513b08
GH-214: [feat] Add dependencies to build.gradle.
wade3hamati Jan 14, 2025
09ccd8b
GH-214: [feat] Add prometheus properties.
wade3hamati Jan 14, 2025
6203b4f
GH-214: [feat] Add ObservationConfig for micrometer observation support.
wade3hamati Jan 14, 2025
49a939b
GH-214: [feat] Make repositories observable.
wade3hamati Jan 14, 2025
b6daf61
GH-214: [feat] Create configuration files for tempo, prometheus, and …
wade3hamati Jan 14, 2025
767e22e
GH-214: [feat] Configure Logback for Loki logging integration.
wade3hamati Jan 14, 2025
50e8894
GH-214: [feat] Add dependencies to build.gradle.
wade3hamati Jan 14, 2025
9fc48a8
GH-214: [feat] Add prometheus properties.
wade3hamati Jan 14, 2025
8250ad1
GH-214: [feat] Add ObservationConfig for micrometer observation support.
wade3hamati Jan 14, 2025
c17649a
GH-214: [feat] Make repositories observable.
wade3hamati Jan 14, 2025
449dfaf
GH-214: [feat] Create configuration files for tempo, prometheus, and …
wade3hamati Jan 14, 2025
c94c162
GH-214: [feat] Configure Logback for Loki logging integration.
wade3hamati Jan 14, 2025
b5b07fa
GH-214: [feat] Create docker-compose with Prometheus, Grafana, and Te…
wade3hamati Feb 19, 2025
92ad080
GH-214: [feat] Create configuration for Prometheus, Grafana, and Tempo.
wade3hamati Feb 19, 2025
5fd85b4
GH-214: [feat] Create Grafana dashboard.
wade3hamati Feb 19, 2025
3b3febc
GH-214: [feat] Import needed dependencies and configure application.p…
wade3hamati Feb 19, 2025
56a2b85
GH-214: [feat] Add needed dependencies to projects.
wade3hamati Feb 19, 2025
2107596
GH-214: [feat] Add needed configuration settings to projects.
wade3hamati Feb 19, 2025
3643eae
GH-214: [feat] Add needed configuration settings to projects.
wade3hamati Feb 19, 2025
c34fbe4
GH-214: [feat] Add ObservationConfig to new messaging-service and sto…
wade3hamati Feb 19, 2025
aa172ec
GH-214: [feat] Solve merge conflicts.
wade3hamati Feb 19, 2025
fea6dc4
GH-214: [feat] Change ports for easy testability and include actuator…
wade3hamati Feb 24, 2025
585bb80
GH-214: [feat] Include all microservices in prometheus config.
wade3hamati Feb 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions Microservices/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions Microservices/email-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions Microservices/email-service/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<springProperty scope="context" name="appName" source="spring.application.name"/>

<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>http://localhost:3100/loki/api/v1/push</url>
</http>
<format>
<label>
<pattern>application=${appName},host=${HOSTNAME},level=%level</pattern>
</label>
<message>
<pattern>${FILE_LOG_PATTERN}</pattern>
</message>
<sortByTime>true</sortByTime>
</format>
</appender>

<root level="INFO">
<appender-ref ref="LOKI"/>
</root>
</configuration>
8 changes: 8 additions & 0 deletions Microservices/event-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) {
"/api-docs",
"/api-docs/**",
"/swagger-ui/**",
"/webjars/**")
"/webjars/**",
"/actuator/**")
.permitAll()
.anyRequest().authenticated())
.csrf(AbstractHttpConfigurer::disable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Event, String> {

Optional<Event> findEventById(String id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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
24 changes: 24 additions & 0 deletions Microservices/event-service/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<springProperty scope="context" name="appName" source="spring.application.name"/>

<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>http://localhost:3100/loki/api/v1/push</url>
</http>
<format>
<label>
<pattern>application=${appName},host=${HOSTNAME},level=%level</pattern>
</label>
<message>
<pattern>${FILE_LOG_PATTERN}</pattern>
</message>
<sortByTime>true</sortByTime>
</format>
</appender>

<root level="INFO">
<appender-ref ref="LOKI"/>
</root>
</configuration>
27 changes: 20 additions & 7 deletions Microservices/gateway/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ plugins {
group = 'app.sportahub'
version = '0.0.1-SNAPSHOT'


java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
Expand All @@ -27,18 +26,23 @@ 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'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
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'
Expand All @@ -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()
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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}
Expand Down Expand Up @@ -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
Loading