Skip to content

Commit 5eb6a3d

Browse files
committed
add opentelemetry
1 parent c3ece1c commit 5eb6a3d

File tree

14 files changed

+314
-10
lines changed

14 files changed

+314
-10
lines changed

docker/docker-compose.yml

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
version: '3.8'
2+
23
services:
4+
otel-collector:
5+
image: otel/opentelemetry-collector-contrib:latest
6+
command: ["--config=/etc/otel-collector-config.yml"]
7+
volumes:
8+
- ./otel-collector-config.yml:/etc/otel-collector-config.yml
9+
ports:
10+
- "4318:4318" # OTLP HTTP
11+
- "9464:9464" # Prometheus scrape
12+
networks:
13+
- monitoring
14+
15+
depends_on:
16+
- tempo
17+
18+
prometheus:
19+
image: prom/prometheus:latest
20+
volumes:
21+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
22+
ports:
23+
- "9090:9090"
24+
networks:
25+
- monitoring
26+
27+
grafana:
28+
image: grafana/grafana:latest
29+
environment:
30+
- GF_SECURITY_ADMIN_USER=admin
31+
- GF_SECURITY_ADMIN_PASSWORD=admin
32+
ports:
33+
- "3001:3000"
34+
networks:
35+
- monitoring
36+
37+
loki:
38+
image: grafana/loki:2.9.2
39+
command: -config.file=/etc/loki/local-config.yaml
40+
ports:
41+
- "3100:3100"
42+
networks:
43+
- monitoring
44+
45+
tempo:
46+
image: grafana/tempo:2.4.1
47+
command: ["-config.file=/etc/tempo.yaml"]
48+
volumes:
49+
- ./tempo.yaml:/etc/tempo.yaml
50+
ports:
51+
- "3200:3200" # API Tempo
52+
networks:
53+
- monitoring
54+
355
postgres:
456
image: postgres:16-alpine
557
container_name: ridesharing_postgres
@@ -17,8 +69,8 @@ services:
1769
interval: 10s
1870
timeout: 5s
1971
retries: 5
20-
volumes:
21-
pgdata:
72+
networks:
73+
- monitoring
2274

2375
keycloak:
2476
image: quay.io/keycloak/keycloak:24.0.3
@@ -27,7 +79,7 @@ volumes:
2779
environment:
2880
KC_DB: postgres
2981
KC_DB_URL_HOST: postgres
30-
KC_DB_URL_DATABASE: ridesharingdb
82+
KC_DB_URL_DATABASE: ridesharingkeycloakdb
3183
KC_DB_USERNAME: postgres
3284
KC_DB_PASSWORD: postgres
3385
KC_HEALTH_ENABLED: true
@@ -41,3 +93,12 @@ volumes:
4193
command: start-dev --import-realm
4294
volumes:
4395
- ./keycloak/realm-templateAuth.json:/opt/keycloak/data/import/realm-templateAuth.json
96+
networks:
97+
- monitoring
98+
99+
volumes:
100+
pgdata:
101+
102+
networks:
103+
monitoring:
104+
driver: bridge

docker/otel-collector-config.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
receivers:
2+
otlp:
3+
protocols:
4+
grpc:
5+
http:
6+
7+
processors:
8+
batch:
9+
send_batch_size: 1024
10+
timeout: 10s
11+
12+
exporters:
13+
prometheus:
14+
endpoint: "0.0.0.0:8889"
15+
otlp/tempo:
16+
endpoint: tempo:4317
17+
tls:
18+
insecure: true
19+
otlphttp:
20+
endpoint: http://loki:3100/otlp # Assuming Loki is accessible via hostname 'loki' on port 3100
21+
service:
22+
pipelines:
23+
metrics:
24+
receivers: [otlp]
25+
processors: [batch]
26+
exporters: [prometheus]
27+
traces:
28+
receivers: [otlp]
29+
processors: [batch]
30+
exporters: [otlp/tempo]
31+
logs:
32+
receivers: [otlp]
33+
processors: [batch]
34+
exporters: [otlphttp]

docker/prometheus.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
global:
2+
scrape_interval: 5s
3+
4+
scrape_configs:
5+
- job_name: "otel-collector"
6+
static_configs:
7+
- targets: ["otel-collector:9464"]

docker/promtail-config.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
server:
2+
http_listen_port: 9080
3+
grpc_listen_port: 0
4+
5+
positions:
6+
filename: /tmp/positions.yaml
7+
8+
clients:
9+
- url: http://loki:3100/loki/api/v1/push
10+
11+
scrape_configs:
12+
- job_name: containers
13+
static_configs:
14+
- targets:
15+
- localhost
16+
labels:
17+
job: varlogs
18+
__path__: /var/log/containers/*.log

docker/tempo.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
auth_enabled: false
2+
server:
3+
http_listen_port: 3200
4+
grpc_listen_port: 9095
5+
log_level: info
6+
log_format: logfmt
7+
8+
distributor:
9+
receivers:
10+
otlp:
11+
protocols:
12+
grpc:
13+
http:
14+
15+
ingester:
16+
trace_idle_period: 10s
17+
max_block_bytes: 1_000_000
18+
max_block_duration: 5m
19+
20+
compactor:
21+
compaction:
22+
compaction_window: 1h
23+
24+
storage:
25+
trace:
26+
backend: local
27+
local:
28+
path: /tmp/tempo

src/RideSharingApp.Api/Controllers/RidesController.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
using Asp.Versioning;
2-
using Microsoft.AspNetCore.Authorization;
32
using Microsoft.AspNetCore.Mvc;
43
using RideSharingApp.Application.Abstractions.Messaging;
54
using RideSharingApp.Application.UseCases.Rides.GetRiders;
65
using RideSharingApp.Application.UseCases.Rides.RequestRiders;
76

87
namespace RideSharingApp.Api.Controllers;
98

10-
[Authorize]
9+
//[Authorize]
1110
[ApiController]
1211
[Route("api/v{version:apiVersion}/[controller]")]
1312
[ApiVersion("1.0")]

src/RideSharingApp.Api/DependencyInjection.cs

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
using Microsoft.AspNetCore.Authentication.JwtBearer;
33
using Microsoft.AspNetCore.ResponseCompression;
44
using Microsoft.IdentityModel.Tokens;
5+
using OpenTelemetry.Logs;
6+
using OpenTelemetry.Metrics;
7+
using OpenTelemetry.Resources;
8+
using OpenTelemetry.Trace;
59
using RideSharingApp.Api.Middlewares;
610
using Serilog;
711

12+
813
namespace RideSharingApp.Api;
914

1015
public static class DependencyInjection
@@ -26,7 +31,8 @@ public static WebApplication UseApi(this WebApplication app)
2631
app
2732
.UseMiddleware<SecurityHeadersMiddleware>()
2833
.UseMiddleware<CorrelationIdMiddleware>()
29-
.UseMiddleware<GlobalExceptionMiddleware>();
34+
.UseMiddleware<GlobalExceptionMiddleware>()
35+
.UseMiddleware<IdempotencyMiddleware>();
3036

3137
return app;
3238
}
@@ -38,6 +44,21 @@ public static WebApplicationBuilder HostSerilog(this WebApplicationBuilder build
3844
loggerConfiguration.WriteTo.Console();
3945
});
4046

47+
var resourceBuilder = ResourceBuilder.CreateDefault()
48+
.AddService("RideSharingAppApi", serviceVersion: "1.0.0");
49+
50+
// ---------- LOGGING ----------
51+
builder.Logging.ClearProviders();
52+
builder.Logging.AddOpenTelemetry(logging =>
53+
{
54+
logging
55+
.SetResourceBuilder(resourceBuilder)
56+
.AddOtlpExporter(o =>
57+
{
58+
o.Endpoint = new Uri("http://otel-collector:4317");
59+
});
60+
});
61+
4162
return builder;
4263
}
4364

@@ -51,7 +72,8 @@ public static IServiceCollection AddApi(this IServiceCollection services, IConfi
5172
.AddVersioning()
5273
.AddSwaggerGen()
5374
.AddCompression()
54-
.UseSerilog(configuration);
75+
.UseSerilog(configuration)
76+
.AddOpenTel();
5577

5678
return services;
5779
}
@@ -146,4 +168,77 @@ private static IServiceCollection UseSerilog(this IServiceCollection services, I
146168

147169
return services;
148170
}
149-
}
171+
172+
private static IServiceCollection AddOpenTel(this IServiceCollection services)
173+
{
174+
var resourceBuilder = ResourceBuilder.CreateDefault()
175+
.AddService("RideSharingAppApi", serviceVersion: "1.0.0");
176+
177+
services.AddOpenTelemetry()
178+
.WithMetrics(metrics =>
179+
{
180+
metrics
181+
.SetResourceBuilder(ResourceBuilder.CreateDefault()
182+
.AddService(nameof(RideSharingApp)))
183+
.AddAspNetCoreInstrumentation()
184+
.AddRuntimeInstrumentation()
185+
.AddProcessInstrumentation()
186+
.AddOtlpExporter(o =>
187+
{
188+
o.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://otel-collector:4318");
189+
});
190+
});
191+
192+
// ---------- MÉTRICAS ----------
193+
services.AddOpenTelemetry()
194+
.WithMetrics(metrics =>
195+
{
196+
metrics
197+
.SetResourceBuilder(resourceBuilder)
198+
.AddAspNetCoreInstrumentation()
199+
.AddRuntimeInstrumentation()
200+
.AddProcessInstrumentation()
201+
.AddMeter("RideSharingAppApiMetrics")
202+
.AddOtlpExporter(o =>
203+
{
204+
o.Endpoint = new Uri("http://otel-collector:4317");
205+
});
206+
});
207+
208+
// ---------- TRACING ----------
209+
services.AddOpenTelemetry()
210+
.WithTracing(tracing =>
211+
{
212+
tracing
213+
.SetResourceBuilder(resourceBuilder)
214+
.AddAspNetCoreInstrumentation()
215+
.AddHttpClientInstrumentation()
216+
.AddOtlpExporter(o =>
217+
{
218+
o.Endpoint = new Uri("http://otel-collector:4317");
219+
});
220+
});
221+
222+
return services;
223+
}
224+
}
225+
226+
//internal class NewRides : INewRides
227+
//{
228+
// private readonly Counter<long> _ordersCounter;
229+
230+
// public NewRides(IMeterProvider meterProvider)
231+
// {
232+
// // Cria um meter via abstração do OpenTelemetry
233+
// var meter = meterProvider.GetMeter("MyAppMetrics");
234+
// _ordersCounter = meter.CreateCounter<long>(
235+
// "orders_total",
236+
// description: "Quantidade total de pedidos criados"
237+
// );
238+
// }
239+
240+
// public void Increment()
241+
// {
242+
// _ordersCounter.Add(1);
243+
// }
244+
//}

src/RideSharingApp.Api/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ COPY --from=build /app/out .
1919
EXPOSE 80
2020
EXPOSE 443
2121

22+
# Configura variáveis padrão do OpenTelemetry
23+
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
24+
ENV OTEL_METRICS_EXPORTER=otlp
25+
ENV OTEL_TRACES_EXPORTER=none
26+
ENV OTEL_LOGS_EXPORTER=none
27+
2228
# Set environment variables if needed
2329
# ENV ASPNETCORE_URLS="http://+:80"
2430

src/RideSharingApp.Api/appsettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"RideConnection": "Host=localhost;Port=5432;Database=ridesharingdb;Username=postgres;Password=postgres"
1111
},
1212
"CurrencyApi": {
13-
"Url": "https://economia.awesomeapi.com.br/json/last/USD-BRL"
13+
"Url": "https://economia.awesomeapi.com.br"
1414
},
1515
"Keycloak": {
1616
"Url": "http://localhost:8080",

src/RideSharingApp.Application/DependencyInjection.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using FluentValidation;
22
using Microsoft.Extensions.DependencyInjection;
33
using RideSharingApp.Application.Abstractions.Messaging;
4+
using RideSharingApp.Application.UseCases.Rides.Metrics;
45
using RideSharingApp.SharedKernel.DomainEvents;
6+
using System.Diagnostics.Metrics;
57

68
namespace RideSharingApp.Application;
79

@@ -10,6 +12,7 @@ public static class DependencyInjection
1012
public static IServiceCollection AddApplication(this IServiceCollection services)
1113
{
1214
services
15+
.AddMeters()
1316
.AddScrutorScan()
1417
.AddValidatorsFromAssembly(typeof(DependencyInjection).Assembly, includeInternalTypes: true);
1518

@@ -36,4 +39,13 @@ private static IServiceCollection AddScrutorScan(this IServiceCollection service
3639

3740
return services;
3841
}
42+
43+
private static IServiceCollection AddMeters(this IServiceCollection services)
44+
{
45+
services.AddSingleton<Meter>(sp => new Meter("RideSharingAppApiMetrics"));
46+
47+
services.AddScoped<INewRides, NewRides>();
48+
49+
return services;
50+
}
3951
}

0 commit comments

Comments
 (0)