# lftraining/lfs148-code architecture

> Architecture diagram of the GitHub repository lftraining/lfs148-code, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/lftraining/lfs148-code
- Repository: https://github.com/lftraining/lfs148-code

## Overview

This repository is a set of OpenTelemetry learning exercises, not one deployed application. The principal workflow is a Flask request that can retrieve a user and return an HTTP response; the exercises progressively add manual logs, metrics, and traces, while the collector example combines those techniques. Separate exercises cover automatic instrumentation and a Spring Boot/Flask/Thymeleaf example. Source excerpts show the collector’s user-client and telemetry setup; other exercise variants are represented from the file tree. The README gives no further capability detail, and the Java/Flask automatic and action examples were not shown in excerpts.

Main entry points: [`exercises/collector/initial/src/app.py`](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/app.py) (Collector Flask App), [`exercises/manual-instrumentation-traces/solution/src/app.py`](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-traces/solution/src/app.py) (Traces Flask App), [`exercises/collector/initial/src/client.py`](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/client.py) (Chaos / Faker Client), [`exercises/collector/initial/src/metric_utils.py`](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/metric_utils.py) (Metric Setup)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_collector["Collector Exercise"]
  node_collector_app["Collector Flask App<br/>[app.py]"]
  node_collector_client["Chaos / Faker Client<br/>[client.py]"]
  node_collector_user["User Model<br/>[user.py]"]
  node_collector_logs["Log Handler<br/>[logging_utils.py]"]
  node_collector_metrics["Metric Setup<br/>[metric_utils.py]"]
  node_collector_traces["Trace Setup<br/>[trace_utils.py]"]
  node_collector_resources["Resource Setup<br/>[resource_utils.py]"]
end

subgraph group_manual["Manual Instrumentation"]
  node_logs_app["Logs Flask App<br/>[app.py]"]
  node_logs_utils["Log Handler<br/>[logging_utils.py]"]
  node_metrics_app["Metrics Flask App<br/>[app.py]"]
  node_metrics_utils["Metric Setup<br/>[metric_utils.py]"]
  node_metrics_resource["Resource Setup<br/>[resource_utils.py]"]
  node_traces_app["Traces Flask App<br/>[app.py]"]
  node_traces_utils["Trace Setup<br/>[trace_utils.py]"]
end

subgraph group_automatic["Automatic Instrumentation"]
  node_auto_flask_initial["Flask UI Exercise<br/>[app.py]"]
  node_auto_flask_solution["Flask UI Solution<br/>[app.py]"]
  node_auto_spring_initial["Spring Backend Exercise"]
  node_auto_spring_solution["Spring Backend Solution"]
end

subgraph group_action["OTel In Action"]
  node_action_flask["Flask UI<br/>[app.py]"]
  node_action_spring["Spring Backend"]
  node_action_thymeleaf["Thymeleaf UI"]
end

node_user(("HTTP Caller"))
node_http_service(("HTTP Service"))

node_user -->|"sends request"| node_collector_app
node_collector_app -->|"gets user"| node_collector_client
node_collector_client -->|"creates user"| node_collector_user
node_collector_app -->|"attaches handler"| node_collector_logs
node_collector_app -->|"sets up metrics"| node_collector_metrics
node_collector_app -->|"creates tracer"| node_collector_traces
node_collector_app -->|"requests service"| node_http_service
node_collector_metrics -->|"creates resource"| node_collector_resources
node_collector_traces -->|"creates resource"| node_collector_resources
node_user -->|"sends request"| node_logs_app
node_logs_app -->|"attaches handler"| node_logs_utils
node_user -->|"sends request"| node_metrics_app
node_metrics_app -->|"sets up metrics"| node_metrics_utils
node_metrics_utils -->|"creates resource"| node_metrics_resource
node_user -->|"sends request"| node_traces_app
node_traces_app -->|"creates tracer"| node_traces_utils
node_traces_app -->|"requests service"| node_http_service

click node_collector_app "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/app.py"
click node_collector_client "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/client.py"
click node_collector_user "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/model/user.py"
click node_collector_logs "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/logging_utils.py"
click node_collector_metrics "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/metric_utils.py"
click node_collector_traces "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/trace_utils.py"
click node_collector_resources "https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/resource_utils.py"
click node_logs_app "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-logs/solution/src/app.py"
click node_logs_utils "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-logs/solution/src/logging_utils.py"
click node_metrics_app "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-metrics/solution/src/app.py"
click node_metrics_utils "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-metrics/solution/src/metric_utils.py"
click node_metrics_resource "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-metrics/solution/src/resource_utils.py"
click node_traces_app "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-traces/solution/src/app.py"
click node_traces_utils "https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-traces/solution/src/trace_utils.py"
click node_auto_flask_initial "https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/initial/todoui-flask/app.py"
click node_auto_flask_solution "https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/solution/todoui-flask/app.py"
click node_auto_spring_initial "https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/initial/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java"
click node_auto_spring_solution "https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java"
click node_action_flask "https://github.com/lftraining/lfs148-code/blob/main/exercises/otel-in-action/todoui-flask/app.py"
click node_action_spring "https://github.com/lftraining/lfs148-code/blob/main/exercises/otel-in-action/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java"
click node_action_thymeleaf "https://github.com/lftraining/lfs148-code/blob/main/exercises/otel-in-action/todoui-thymeleaf/src/main/java/io/novatec/todoui/TodouiApplication.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_collector_app,node_collector_client,node_collector_user,node_collector_logs,node_collector_metrics,node_collector_traces,node_collector_resources toneBlue
class node_logs_app,node_logs_utils,node_metrics_app,node_metrics_utils,node_metrics_resource,node_traces_app,node_traces_utils toneAmber
class node_auto_flask_initial,node_auto_flask_solution,node_auto_spring_initial,node_auto_spring_solution toneMint
class node_action_flask,node_action_spring,node_action_thymeleaf toneRose
class node_user,node_http_service toneIndigo
```

## Components

### Collector Exercise

- [Collector Flask App](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/app.py): `exercises/collector/initial/src/app.py`
- [Chaos / Faker Client](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/client.py): `exercises/collector/initial/src/client.py`
- [User Model](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/model/user.py): `exercises/collector/initial/src/model/user.py`
- [Log Handler](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/logging_utils.py): `exercises/collector/initial/src/logging_utils.py`
- [Metric Setup](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/metric_utils.py): `exercises/collector/initial/src/metric_utils.py`
- [Trace Setup](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/trace_utils.py): `exercises/collector/initial/src/trace_utils.py`
- [Resource Setup](https://github.com/lftraining/lfs148-code/blob/main/exercises/collector/initial/src/resource_utils.py): `exercises/collector/initial/src/resource_utils.py`

### Manual Instrumentation

- [Logs Flask App](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-logs/solution/src/app.py): `exercises/manual-instrumentation-logs/solution/src/app.py`
- [Log Handler](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-logs/solution/src/logging_utils.py): `exercises/manual-instrumentation-logs/solution/src/logging_utils.py`
- [Metrics Flask App](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-metrics/solution/src/app.py): `exercises/manual-instrumentation-metrics/solution/src/app.py`
- [Metric Setup](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-metrics/solution/src/metric_utils.py): `exercises/manual-instrumentation-metrics/solution/src/metric_utils.py`
- [Resource Setup](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-metrics/solution/src/resource_utils.py): `exercises/manual-instrumentation-metrics/solution/src/resource_utils.py`
- [Traces Flask App](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-traces/solution/src/app.py): `exercises/manual-instrumentation-traces/solution/src/app.py`
- [Trace Setup](https://github.com/lftraining/lfs148-code/blob/main/exercises/manual-instrumentation-traces/solution/src/trace_utils.py): `exercises/manual-instrumentation-traces/solution/src/trace_utils.py`

### Automatic Instrumentation

- [Flask UI Exercise](https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/initial/todoui-flask/app.py): `exercises/automatic-instrumentation/initial/todoui-flask/app.py`
- [Flask UI Solution](https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/solution/todoui-flask/app.py): `exercises/automatic-instrumentation/solution/todoui-flask/app.py`
- [Spring Backend Exercise](https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/initial/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java): `exercises/automatic-instrumentation/initial/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java`
- [Spring Backend Solution](https://github.com/lftraining/lfs148-code/blob/main/exercises/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java): `exercises/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java`

### OTel In Action

- [Flask UI](https://github.com/lftraining/lfs148-code/blob/main/exercises/otel-in-action/todoui-flask/app.py): `exercises/otel-in-action/todoui-flask/app.py`
- [Spring Backend](https://github.com/lftraining/lfs148-code/blob/main/exercises/otel-in-action/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java): `exercises/otel-in-action/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java`
- [Thymeleaf UI](https://github.com/lftraining/lfs148-code/blob/main/exercises/otel-in-action/todoui-thymeleaf/src/main/java/io/novatec/todoui/TodouiApplication.java): `exercises/otel-in-action/todoui-thymeleaf/src/main/java/io/novatec/todoui/TodouiApplication.java`

### Other components

- **HTTP Caller**
- **HTTP Service**

## Connections

- HTTP Caller → Collector Flask App: sends request (evidence: `exercises/collector/initial/src/app.py`)
- Collector Flask App → Chaos / Faker Client: gets user (evidence: `exercises/collector/initial/src/app.py`)
- Chaos / Faker Client → User Model: creates user (evidence: `exercises/collector/initial/src/client.py`)
- Collector Flask App → Log Handler: attaches handler (evidence: `exercises/collector/initial/src/app.py`)
- Collector Flask App → Metric Setup: sets up metrics (evidence: `exercises/collector/initial/src/app.py`)
- Collector Flask App → Trace Setup: creates tracer (evidence: `exercises/collector/initial/src/app.py`)
- Collector Flask App → HTTP Service: requests service (evidence: `exercises/collector/initial/src/app.py`)
- Metric Setup → Resource Setup: creates resource (evidence: `exercises/collector/initial/src/metric_utils.py`)
- Trace Setup → Resource Setup: creates resource (evidence: `exercises/collector/initial/src/trace_utils.py`)
- HTTP Caller → Logs Flask App: sends request (evidence: `exercises/manual-instrumentation-logs/solution/src/app.py`)
- Logs Flask App → Log Handler: attaches handler (evidence: `exercises/manual-instrumentation-logs/solution/src/app.py`)
- HTTP Caller → Metrics Flask App: sends request (evidence: `exercises/manual-instrumentation-metrics/solution/src/app.py`)
- Metrics Flask App → Metric Setup: sets up metrics (evidence: `exercises/manual-instrumentation-metrics/solution/src/app.py`)
- Metric Setup → Resource Setup: creates resource (evidence: `exercises/manual-instrumentation-metrics/solution/src/metric_utils.py`)
- HTTP Caller → Traces Flask App: sends request (evidence: `exercises/manual-instrumentation-traces/solution/src/app.py`)
- Traces Flask App → Trace Setup: creates tracer (evidence: `exercises/manual-instrumentation-traces/solution/src/app.py`)
- Traces Flask App → HTTP Service: requests service (evidence: `exercises/manual-instrumentation-traces/solution/src/app.py`)
