initial commit

This commit is contained in:
2026-02-16 17:36:47 +11:00
commit cb84fe3411
10 changed files with 272 additions and 0 deletions

49
.gitignore vendored Normal file
View File

@@ -0,0 +1,49 @@
*.swp
*.*~
project.lock.json
.DS_Store
*.pyc
nupkg/
# Visual Studio Code
.vscode/*
!.vscode/settings.json
# Rider
.idea/
# Visual Studio
.vs/
# Fleet
.fleet/
# Code Rush
.cr/
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
msbuild.log
msbuild.err
msbuild.wrn
# Node.js build artifacts
node_modules/
package-lock.json
package.json

14
LoggingApi.csproj Normal file
View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenTelemetry" Version="1.15.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.0" />
</ItemGroup>
</Project>

24
LoggingApi.sln Normal file
View File

@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggingApi", "LoggingApi.csproj", "{06EE0C43-C200-C32E-7D42-5A6E5B7F26C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{06EE0C43-C200-C32E-7D42-5A6E5B7F26C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{06EE0C43-C200-C32E-7D42-5A6E5B7F26C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06EE0C43-C200-C32E-7D42-5A6E5B7F26C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06EE0C43-C200-C32E-7D42-5A6E5B7F26C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A4C3FE80-F377-4609-9507-B69321D4CB00}
EndGlobalSection
EndGlobal

33
Program.cs Normal file
View File

@@ -0,0 +1,33 @@
using OpenTelemetry.Logs;
var builder = WebApplication.CreateBuilder(args);
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
if (useOtlpExporter)
{
logging.AddOtlpExporter();
}
else
{
Console.WriteLine("OTEL_EXPORTER_OTLP_ENDPOINT is not set. Skipping OTLP exporter configuration.");
}
});
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/log", (ILogger<Program> logger) =>
{
if (logger.IsEnabled(LogLevel.Information))
logger.LogInformation("Logging a message at {time:HH:mm:ss} on {machine}", DateTime.Now, Environment.MachineName);
return Results.Ok();
});
app.Run();

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5171",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7247;http://localhost:5171",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
"OTEL_SERVICE_NAME": "LoggingApi"
}

9
appsettings.json Normal file
View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

51
compose.yml Normal file
View File

@@ -0,0 +1,51 @@
services:
alloy:
image: grafana/alloy:v1.13.1
ports:
- 12345:12345
- 4317:4317
- 4318:4318
volumes:
- ./config.alloy:/etc/alloy/config.alloy
command: run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy
depends_on:
- loki
loki:
image: grafana/loki:3.5.10
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
- loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
grafana:
image: grafana/grafana:12.3
environment:
- GF_FEATURE_TOGGLES_ENABLE=grafanaManagedRecordingRules
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_BASIC_ENABLED=false
ports:
- 3001:3000/tcp
entrypoint:
- sh
- -euc
- |
mkdir -p /etc/grafana/provisioning/datasources
cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
apiVersion: 1
datasources:
- name: Loki
type: loki
access: proxy
orgId: 1
url: 'http://loki:3100'
basicAuth: false
isDefault: true
version: 1
editable: true
EOF
/run.sh
volumes:
loki-data:

24
config.alloy Normal file
View File

@@ -0,0 +1,24 @@
otelcol.receiver.otlp "default" {
http {
endpoint = "0.0.0.0:4318"
}
grpc {
endpoint = "0.0.0.0:4317"
}
output {
logs = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch "default" {
output {
logs = [otelcol.exporter.otlphttp.loki.input]
}
}
otelcol.exporter.otlphttp "loki" {
client {
endpoint = "http://loki:3100/otlp"
}
}

35
loki-config.yaml Normal file
View File

@@ -0,0 +1,35 @@
auth_enabled: false
server:
http_listen_port: 3100
common:
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
replication_factor: 1
path_prefix: /loki
schema_config:
configs:
- from: 2020-05-15
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
filesystem:
directory: /loki/chunks
compactor:
working_directory: /loki/compactor
retention_enabled: true
compaction_interval: 24h
delete_request_store: filesystem
limits_config:
retention_period: 720h # 30 days