container-superposition 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/README.md +843 -0
  2. package/dist/scripts/init.d.ts +3 -0
  3. package/dist/scripts/init.d.ts.map +1 -0
  4. package/dist/scripts/init.js +1190 -0
  5. package/dist/scripts/init.js.map +1 -0
  6. package/dist/scripts/migrate-to-manifests.d.ts +12 -0
  7. package/dist/scripts/migrate-to-manifests.d.ts.map +1 -0
  8. package/dist/scripts/migrate-to-manifests.js +230 -0
  9. package/dist/scripts/migrate-to-manifests.js.map +1 -0
  10. package/dist/tool/questionnaire/composer.d.ts +6 -0
  11. package/dist/tool/questionnaire/composer.d.ts.map +1 -0
  12. package/dist/tool/questionnaire/composer.js +1232 -0
  13. package/dist/tool/questionnaire/composer.js.map +1 -0
  14. package/dist/tool/readme/markdown-parser.d.ts +30 -0
  15. package/dist/tool/readme/markdown-parser.d.ts.map +1 -0
  16. package/dist/tool/readme/markdown-parser.js +139 -0
  17. package/dist/tool/readme/markdown-parser.js.map +1 -0
  18. package/dist/tool/readme/readme-generator.d.ts +9 -0
  19. package/dist/tool/readme/readme-generator.d.ts.map +1 -0
  20. package/dist/tool/readme/readme-generator.js +422 -0
  21. package/dist/tool/readme/readme-generator.js.map +1 -0
  22. package/dist/tool/schema/custom-loader.d.ts +17 -0
  23. package/dist/tool/schema/custom-loader.d.ts.map +1 -0
  24. package/dist/tool/schema/custom-loader.js +149 -0
  25. package/dist/tool/schema/custom-loader.js.map +1 -0
  26. package/dist/tool/schema/overlay-loader.d.ts +47 -0
  27. package/dist/tool/schema/overlay-loader.d.ts.map +1 -0
  28. package/dist/tool/schema/overlay-loader.js +252 -0
  29. package/dist/tool/schema/overlay-loader.js.map +1 -0
  30. package/dist/tool/schema/types.d.ts +212 -0
  31. package/dist/tool/schema/types.d.ts.map +1 -0
  32. package/dist/tool/schema/types.js +5 -0
  33. package/dist/tool/schema/types.js.map +1 -0
  34. package/docs/README.md +308 -0
  35. package/docs/architecture.md +233 -0
  36. package/docs/creating-overlays.md +549 -0
  37. package/docs/custom-patches.md +540 -0
  38. package/docs/dependencies.md +279 -0
  39. package/docs/examples/custom-patches-example.md +85 -0
  40. package/docs/examples.md +576 -0
  41. package/docs/messaging-comparison.md +265 -0
  42. package/docs/messaging-quick-start.md +385 -0
  43. package/docs/observability-workflow.md +537 -0
  44. package/docs/overlay-manifest-refactoring.md +214 -0
  45. package/docs/overlay-metadata-archive.md +54 -0
  46. package/docs/overlays.md +523 -0
  47. package/docs/presets-architecture.md +498 -0
  48. package/docs/presets.md +366 -0
  49. package/docs/publishing.md +476 -0
  50. package/docs/quick-reference.md +326 -0
  51. package/docs/ux.md +170 -0
  52. package/features/README.md +85 -0
  53. package/features/cross-distro-packages/README.md +146 -0
  54. package/features/cross-distro-packages/devcontainer-feature.json +20 -0
  55. package/features/cross-distro-packages/install.sh +58 -0
  56. package/features/local-secrets-manager/devcontainer-feature.json +18 -0
  57. package/features/local-secrets-manager/install.sh +127 -0
  58. package/features/project-scaffolder/devcontainer-feature.json +24 -0
  59. package/features/project-scaffolder/install.sh +100 -0
  60. package/features/team-conventions/devcontainer-feature.json +24 -0
  61. package/features/team-conventions/install.sh +93 -0
  62. package/overlays/.registry/README.md +14 -0
  63. package/overlays/.registry/base-images.yml +26 -0
  64. package/overlays/.registry/base-templates.yml +7 -0
  65. package/overlays/README.md +155 -0
  66. package/overlays/alertmanager/.env.example +5 -0
  67. package/overlays/alertmanager/README.md +465 -0
  68. package/overlays/alertmanager/alert-rules.yml +56 -0
  69. package/overlays/alertmanager/alertmanager.yml +42 -0
  70. package/overlays/alertmanager/devcontainer.patch.json +12 -0
  71. package/overlays/alertmanager/docker-compose.yml +20 -0
  72. package/overlays/alertmanager/overlay.yml +17 -0
  73. package/overlays/alertmanager/setup.sh +53 -0
  74. package/overlays/alertmanager/verify.sh +31 -0
  75. package/overlays/aws-cli/README.md +473 -0
  76. package/overlays/aws-cli/devcontainer.patch.json +13 -0
  77. package/overlays/aws-cli/overlay.yml +13 -0
  78. package/overlays/azure-cli/README.md +551 -0
  79. package/overlays/azure-cli/devcontainer.patch.json +8 -0
  80. package/overlays/azure-cli/overlay.yml +13 -0
  81. package/overlays/bun/README.md +312 -0
  82. package/overlays/bun/devcontainer.patch.json +41 -0
  83. package/overlays/bun/overlay.yml +16 -0
  84. package/overlays/bun/setup.sh +79 -0
  85. package/overlays/bun/verify.sh +30 -0
  86. package/overlays/codex/README.md +128 -0
  87. package/overlays/codex/devcontainer.patch.json +3 -0
  88. package/overlays/codex/overlay.yml +14 -0
  89. package/overlays/codex/setup.sh +24 -0
  90. package/overlays/codex/verify.sh +30 -0
  91. package/overlays/commitlint/README.md +333 -0
  92. package/overlays/commitlint/devcontainer.patch.json +8 -0
  93. package/overlays/commitlint/overlay.yml +16 -0
  94. package/overlays/commitlint/setup.sh +234 -0
  95. package/overlays/direnv/README.md +504 -0
  96. package/overlays/direnv/devcontainer.patch.json +6 -0
  97. package/overlays/direnv/overlay.yml +13 -0
  98. package/overlays/direnv/setup.sh +139 -0
  99. package/overlays/docker-in-docker/README.md +534 -0
  100. package/overlays/docker-in-docker/devcontainer.patch.json +10 -0
  101. package/overlays/docker-in-docker/overlay.yml +13 -0
  102. package/overlays/docker-sock/README.md +256 -0
  103. package/overlays/docker-sock/devcontainer.patch.json +9 -0
  104. package/overlays/docker-sock/docker-compose.yml +8 -0
  105. package/overlays/docker-sock/overlay.yml +13 -0
  106. package/overlays/dotnet/README.md +147 -0
  107. package/overlays/dotnet/devcontainer.patch.json +51 -0
  108. package/overlays/dotnet/global-tools.txt +24 -0
  109. package/overlays/dotnet/overlay.yml +13 -0
  110. package/overlays/dotnet/setup.sh +51 -0
  111. package/overlays/dotnet/verify.sh +26 -0
  112. package/overlays/gcloud/README.md +269 -0
  113. package/overlays/gcloud/devcontainer.patch.json +14 -0
  114. package/overlays/gcloud/overlay.yml +14 -0
  115. package/overlays/gcloud/verify.sh +52 -0
  116. package/overlays/git-helpers/README.md +168 -0
  117. package/overlays/git-helpers/devcontainer.patch.json +33 -0
  118. package/overlays/git-helpers/overlay.yml +15 -0
  119. package/overlays/git-helpers/setup.sh +91 -0
  120. package/overlays/go/README.md +293 -0
  121. package/overlays/go/devcontainer.patch.json +43 -0
  122. package/overlays/go/overlay.yml +15 -0
  123. package/overlays/go/setup.sh +33 -0
  124. package/overlays/go/verify.sh +40 -0
  125. package/overlays/grafana/.env.example +9 -0
  126. package/overlays/grafana/README.md +462 -0
  127. package/overlays/grafana/dashboard-provider.yml +11 -0
  128. package/overlays/grafana/dashboards/observability-overview.json +263 -0
  129. package/overlays/grafana/devcontainer.patch.json +12 -0
  130. package/overlays/grafana/docker-compose.yml +27 -0
  131. package/overlays/grafana/grafana-datasources.yml +57 -0
  132. package/overlays/grafana/overlay.yml +21 -0
  133. package/overlays/grafana/verify.sh +34 -0
  134. package/overlays/jaeger/.env.example +7 -0
  135. package/overlays/jaeger/README.md +867 -0
  136. package/overlays/jaeger/devcontainer.patch.json +12 -0
  137. package/overlays/jaeger/docker-compose.yml +17 -0
  138. package/overlays/jaeger/overlay.yml +19 -0
  139. package/overlays/java/README.md +267 -0
  140. package/overlays/java/devcontainer.patch.json +44 -0
  141. package/overlays/java/overlay.yml +16 -0
  142. package/overlays/java/setup.sh +41 -0
  143. package/overlays/java/verify.sh +42 -0
  144. package/overlays/just/README.md +443 -0
  145. package/overlays/just/devcontainer.patch.json +3 -0
  146. package/overlays/just/overlay.yml +13 -0
  147. package/overlays/just/setup.sh +182 -0
  148. package/overlays/kubectl-helm/README.md +660 -0
  149. package/overlays/kubectl-helm/devcontainer.patch.json +10 -0
  150. package/overlays/kubectl-helm/overlay.yml +13 -0
  151. package/overlays/loki/.env.example +5 -0
  152. package/overlays/loki/README.md +1156 -0
  153. package/overlays/loki/devcontainer.patch.json +12 -0
  154. package/overlays/loki/docker-compose.yml +18 -0
  155. package/overlays/loki/loki-config.yaml +45 -0
  156. package/overlays/loki/overlay.yml +17 -0
  157. package/overlays/minio/.env.example +9 -0
  158. package/overlays/minio/README.md +639 -0
  159. package/overlays/minio/devcontainer.patch.json +30 -0
  160. package/overlays/minio/docker-compose.yml +28 -0
  161. package/overlays/minio/overlay.yml +18 -0
  162. package/overlays/minio/setup.sh +61 -0
  163. package/overlays/minio/verify.sh +64 -0
  164. package/overlays/mkdocs/README.md +309 -0
  165. package/overlays/mkdocs/devcontainer.patch.json +24 -0
  166. package/overlays/mkdocs/overlay.yml +15 -0
  167. package/overlays/modern-cli-tools/README.md +556 -0
  168. package/overlays/modern-cli-tools/devcontainer.patch.json +3 -0
  169. package/overlays/modern-cli-tools/overlay.yml +13 -0
  170. package/overlays/modern-cli-tools/setup.sh +153 -0
  171. package/overlays/mongodb/.env.example +9 -0
  172. package/overlays/mongodb/README.md +481 -0
  173. package/overlays/mongodb/devcontainer.patch.json +32 -0
  174. package/overlays/mongodb/docker-compose.yml +44 -0
  175. package/overlays/mongodb/overlay.yml +17 -0
  176. package/overlays/mongodb/verify.sh +48 -0
  177. package/overlays/mysql/.env.example +11 -0
  178. package/overlays/mysql/README.md +542 -0
  179. package/overlays/mysql/devcontainer.patch.json +34 -0
  180. package/overlays/mysql/docker-compose.yml +55 -0
  181. package/overlays/mysql/overlay.yml +16 -0
  182. package/overlays/mysql/verify.sh +48 -0
  183. package/overlays/nats/.env.example +5 -0
  184. package/overlays/nats/README.md +762 -0
  185. package/overlays/nats/devcontainer.patch.json +24 -0
  186. package/overlays/nats/docker-compose.yml +31 -0
  187. package/overlays/nats/overlay.yml +18 -0
  188. package/overlays/nats/verify.sh +50 -0
  189. package/overlays/ngrok/README.md +503 -0
  190. package/overlays/ngrok/devcontainer.patch.json +3 -0
  191. package/overlays/ngrok/overlay.yml +14 -0
  192. package/overlays/ngrok/setup.sh +125 -0
  193. package/overlays/nodejs/README.md +192 -0
  194. package/overlays/nodejs/devcontainer.patch.json +49 -0
  195. package/overlays/nodejs/global-packages.txt +16 -0
  196. package/overlays/nodejs/overlay.yml +14 -0
  197. package/overlays/nodejs/setup.sh +46 -0
  198. package/overlays/nodejs/verify.sh +32 -0
  199. package/overlays/otel-collector/.env.example +9 -0
  200. package/overlays/otel-collector/README.md +1257 -0
  201. package/overlays/otel-collector/devcontainer.patch.json +28 -0
  202. package/overlays/otel-collector/docker-compose.yml +22 -0
  203. package/overlays/otel-collector/otel-collector-config.yaml +68 -0
  204. package/overlays/otel-collector/overlay.yml +21 -0
  205. package/overlays/otel-collector/setup.sh +49 -0
  206. package/overlays/otel-demo-nodejs/.env.example +2 -0
  207. package/overlays/otel-demo-nodejs/Dockerfile-otel-demo-nodejs +17 -0
  208. package/overlays/otel-demo-nodejs/README.md +409 -0
  209. package/overlays/otel-demo-nodejs/devcontainer.patch.json +12 -0
  210. package/overlays/otel-demo-nodejs/docker-compose.yml +19 -0
  211. package/overlays/otel-demo-nodejs/overlay.yml +23 -0
  212. package/overlays/otel-demo-nodejs/package-otel-demo-nodejs.json +20 -0
  213. package/overlays/otel-demo-nodejs/server-otel-demo-nodejs.js +259 -0
  214. package/overlays/otel-demo-nodejs/tracing-otel-demo-nodejs.js +57 -0
  215. package/overlays/otel-demo-nodejs/verify.sh +31 -0
  216. package/overlays/otel-demo-python/.env.example +2 -0
  217. package/overlays/otel-demo-python/Dockerfile-otel-demo-python +16 -0
  218. package/overlays/otel-demo-python/README.md +82 -0
  219. package/overlays/otel-demo-python/app-otel-demo-python.py +208 -0
  220. package/overlays/otel-demo-python/devcontainer.patch.json +12 -0
  221. package/overlays/otel-demo-python/docker-compose.yml +19 -0
  222. package/overlays/otel-demo-python/overlay.yml +23 -0
  223. package/overlays/otel-demo-python/requirements-otel-demo-python.txt +4 -0
  224. package/overlays/otel-demo-python/verify.sh +31 -0
  225. package/overlays/playwright/README.md +629 -0
  226. package/overlays/playwright/devcontainer.patch.json +9 -0
  227. package/overlays/playwright/overlay.yml +13 -0
  228. package/overlays/postgres/.env.example +6 -0
  229. package/overlays/postgres/README.md +602 -0
  230. package/overlays/postgres/devcontainer.patch.json +21 -0
  231. package/overlays/postgres/docker-compose.yml +22 -0
  232. package/overlays/postgres/overlay.yml +15 -0
  233. package/overlays/postgres/verify.sh +45 -0
  234. package/overlays/powershell/README.md +314 -0
  235. package/overlays/powershell/devcontainer.patch.json +22 -0
  236. package/overlays/powershell/overlay.yml +13 -0
  237. package/overlays/powershell/setup.sh +29 -0
  238. package/overlays/powershell/verify.sh +38 -0
  239. package/overlays/pre-commit/README.md +263 -0
  240. package/overlays/pre-commit/devcontainer.patch.json +9 -0
  241. package/overlays/pre-commit/overlay.yml +16 -0
  242. package/overlays/pre-commit/setup.sh +129 -0
  243. package/overlays/presets/docs-site.yml +118 -0
  244. package/overlays/presets/fullstack.yml +181 -0
  245. package/overlays/presets/microservice.yml +118 -0
  246. package/overlays/presets/web-api.yml +109 -0
  247. package/overlays/prometheus/.env.example +5 -0
  248. package/overlays/prometheus/README.md +1246 -0
  249. package/overlays/prometheus/devcontainer.patch.json +12 -0
  250. package/overlays/prometheus/docker-compose.yml +22 -0
  251. package/overlays/prometheus/overlay.yml +17 -0
  252. package/overlays/prometheus/prometheus.yml +12 -0
  253. package/overlays/prometheus/verify.sh +34 -0
  254. package/overlays/promtail/.env.example +2 -0
  255. package/overlays/promtail/README.md +357 -0
  256. package/overlays/promtail/devcontainer.patch.json +5 -0
  257. package/overlays/promtail/docker-compose.yml +16 -0
  258. package/overlays/promtail/overlay.yml +17 -0
  259. package/overlays/promtail/promtail-config.yaml +60 -0
  260. package/overlays/promtail/verify.sh +31 -0
  261. package/overlays/pulumi/README.md +472 -0
  262. package/overlays/pulumi/devcontainer.patch.json +13 -0
  263. package/overlays/pulumi/overlay.yml +14 -0
  264. package/overlays/pulumi/verify.sh +31 -0
  265. package/overlays/python/README.md +919 -0
  266. package/overlays/python/devcontainer.patch.json +41 -0
  267. package/overlays/python/overlay.yml +12 -0
  268. package/overlays/python/requirements-overlay.txt +13 -0
  269. package/overlays/python/setup.sh +47 -0
  270. package/overlays/python/verify.sh +32 -0
  271. package/overlays/rabbitmq/.env.example +7 -0
  272. package/overlays/rabbitmq/README.md +680 -0
  273. package/overlays/rabbitmq/devcontainer.patch.json +28 -0
  274. package/overlays/rabbitmq/docker-compose.yml +30 -0
  275. package/overlays/rabbitmq/overlay.yml +18 -0
  276. package/overlays/rabbitmq/verify.sh +41 -0
  277. package/overlays/redis/.env.example +4 -0
  278. package/overlays/redis/README.md +776 -0
  279. package/overlays/redis/devcontainer.patch.json +21 -0
  280. package/overlays/redis/docker-compose.yml +21 -0
  281. package/overlays/redis/overlay.yml +15 -0
  282. package/overlays/redis/verify.sh +41 -0
  283. package/overlays/redpanda/.env.example +10 -0
  284. package/overlays/redpanda/README.md +703 -0
  285. package/overlays/redpanda/devcontainer.patch.json +37 -0
  286. package/overlays/redpanda/docker-compose.yml +67 -0
  287. package/overlays/redpanda/overlay.yml +21 -0
  288. package/overlays/redpanda/verify.sh +48 -0
  289. package/overlays/rust/README.md +299 -0
  290. package/overlays/rust/devcontainer.patch.json +39 -0
  291. package/overlays/rust/overlay.yml +15 -0
  292. package/overlays/rust/setup.sh +36 -0
  293. package/overlays/rust/verify.sh +51 -0
  294. package/overlays/sqlite/README.md +584 -0
  295. package/overlays/sqlite/devcontainer.patch.json +14 -0
  296. package/overlays/sqlite/overlay.yml +15 -0
  297. package/overlays/sqlite/setup.sh +27 -0
  298. package/overlays/sqlite/verify.sh +43 -0
  299. package/overlays/sqlserver/.env.example +6 -0
  300. package/overlays/sqlserver/README.md +592 -0
  301. package/overlays/sqlserver/devcontainer.patch.json +22 -0
  302. package/overlays/sqlserver/docker-compose.yml +32 -0
  303. package/overlays/sqlserver/overlay.yml +17 -0
  304. package/overlays/sqlserver/verify.sh +30 -0
  305. package/overlays/tempo/.env.example +5 -0
  306. package/overlays/tempo/README.md +273 -0
  307. package/overlays/tempo/devcontainer.patch.json +12 -0
  308. package/overlays/tempo/docker-compose.yml +20 -0
  309. package/overlays/tempo/overlay.yml +20 -0
  310. package/overlays/tempo/tempo-config.yaml +32 -0
  311. package/overlays/tempo/verify.sh +31 -0
  312. package/overlays/terraform/README.md +389 -0
  313. package/overlays/terraform/devcontainer.patch.json +15 -0
  314. package/overlays/terraform/overlay.yml +14 -0
  315. package/overlays/terraform/verify.sh +63 -0
  316. package/package.json +74 -0
  317. package/templates/README.md +285 -0
  318. package/templates/compose/.devcontainer/devcontainer.json +46 -0
  319. package/templates/compose/.devcontainer/docker-compose.yml +12 -0
  320. package/templates/compose/README.md +20 -0
  321. package/templates/plain/.devcontainer/devcontainer.json +35 -0
  322. package/templates/plain/README.md +21 -0
  323. package/tool/README.md +281 -0
  324. package/tool/schema/base-images.schema.json +43 -0
  325. package/tool/schema/base-templates.schema.json +34 -0
  326. package/tool/schema/config.schema.json +71 -0
  327. package/tool/schema/overlay-manifest.schema.json +86 -0
@@ -0,0 +1,1156 @@
1
+ # Loki Overlay
2
+
3
+ Multi-tenant log aggregation system designed for storing and querying logs from all your applications and infrastructure.
4
+
5
+ ## Features
6
+
7
+ - **Grafana Loki** - Horizontally scalable, highly available log aggregation
8
+ - **LogQL query language** - Inspired by PromQL for familiar syntax
9
+ - **Label-based indexing** - Cost-effective storage with selective indexing
10
+ - **Persistent storage** - Filesystem-backed with BoltDB
11
+ - **Multi-tenancy support** - Isolated log streams per tenant
12
+ - **Native Grafana integration** - Seamless visualization in Grafana
13
+ - **Compressed storage** - Efficient log storage with compression
14
+
15
+ ## How It Works
16
+
17
+ Loki is a log aggregation system inspired by Prometheus. Unlike traditional log systems that index the entire log line, Loki only indexes metadata (labels), making it extremely cost-effective for storing large volumes of logs.
18
+
19
+ **Architecture:**
20
+
21
+ ```mermaid
22
+ graph TD
23
+ A[Application<br/>Sends logs via OTLP<br/>Or via Promtail shipper] -->|HTTP POST| B[Grafana Loki<br/>Ingester → Storage<br/>Index labels only<br/>Store logs compressed<br/>Query via LogQL<br/>API: http://...:3100]
24
+ B -->|Query| C[Grafana Dashboard<br/>Explore logs<br/>Build dashboards<br/>Alert on log patterns]
25
+ ```
26
+
27
+ **Key Concepts:**
28
+
29
+ - **Labels** - Indexed metadata (service, level, host)
30
+ - **Log streams** - Unique combination of labels
31
+ - **Chunks** - Compressed log data stored on disk
32
+ - **LogQL** - Query language for filtering and aggregating logs
33
+
34
+ ## Configuration
35
+
36
+ ### Ports
37
+
38
+ - `3100` - Loki HTTP API (push, query, health)
39
+
40
+ ### Environment Variables
41
+
42
+ The overlay includes a `.env.example` file. Copy it to `.env` and customize:
43
+
44
+ ```bash
45
+ cd .devcontainer
46
+ cp .env.example .env
47
+ ```
48
+
49
+ **Available variables:**
50
+
51
+ ```bash
52
+ # Loki version
53
+ LOKI_VERSION=latest
54
+
55
+ # Loki port (default 3100)
56
+ LOKI_PORT=3100
57
+ ```
58
+
59
+ ### Loki Configuration File
60
+
61
+ Loki is configured via `loki-config.yaml`:
62
+
63
+ **Key sections:**
64
+
65
+ ```yaml
66
+ auth_enabled: false # Disable multi-tenancy auth
67
+
68
+ server:
69
+ http_listen_port: 3100 # HTTP API port
70
+
71
+ ingester: # In-memory log processing
72
+ chunk_idle_period: 5m # How long before flushing chunks
73
+ chunk_retain_period: 30s # Retain in memory after flush
74
+
75
+ schema_config: # Index schema
76
+ configs:
77
+ - from: 2020-10-24
78
+ store: boltdb-shipper # Index storage
79
+ object_store: filesystem
80
+ schema: v11
81
+
82
+ storage_config: # Where to store data
83
+ boltdb_shipper:
84
+ active_index_directory: /loki/index
85
+ filesystem:
86
+ directory: /loki/chunks
87
+
88
+ limits_config:
89
+ reject_old_samples: true # Reject logs older than 168h
90
+ reject_old_samples_max_age: 168h
91
+ ```
92
+
93
+ ### Enabling Retention
94
+
95
+ Edit `loki-config.yaml` to enable automatic log deletion:
96
+
97
+ ```yaml
98
+ limits_config:
99
+ retention_deletes_enabled: true
100
+ retention_period: 168h # 7 days for development
101
+
102
+ compactor:
103
+ working_directory: /loki/compactor
104
+ shared_store: filesystem
105
+ compaction_interval: 10m
106
+ retention_enabled: true
107
+ retention_delete_delay: 2h
108
+ retention_delete_worker_count: 150
109
+ ```
110
+
111
+ ### Adjusting Performance
112
+
113
+ ```yaml
114
+ ingester:
115
+ chunk_idle_period: 10m # Longer period = larger chunks
116
+ chunk_block_size: 262144 # 256KB chunks
117
+ chunk_retain_period: 1m # Keep in memory longer
118
+ max_chunk_age: 2h # Force flush after 2h
119
+
120
+ limits_config:
121
+ ingestion_rate_mb: 10 # Max MB/s per stream
122
+ ingestion_burst_size_mb: 20
123
+ max_streams_per_user: 10000
124
+ max_line_size: 256000 # 256KB max line size
125
+ ```
126
+
127
+ ### Port Configuration
128
+
129
+ Ports can be changed via `--port-offset`:
130
+
131
+ ```bash
132
+ # Offset all ports by 100
133
+ container-superposition --port-offset 100
134
+
135
+ # Loki will be on 3200 instead of 3100
136
+ ```
137
+
138
+ ## Sending Logs to Loki
139
+
140
+ ### Via OpenTelemetry Collector (Recommended)
141
+
142
+ The otel-collector overlay is pre-configured to forward logs to Loki:
143
+
144
+ ```javascript
145
+ // Node.js - Send logs via OTLP
146
+ const { logs } = require('@opentelemetry/api-logs');
147
+ const { LoggerProvider } = require('@opentelemetry/sdk-logs');
148
+ const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
149
+
150
+ const loggerProvider = new LoggerProvider();
151
+ loggerProvider.addLogRecordProcessor(
152
+ new BatchLogRecordProcessor(
153
+ new OTLPLogExporter({
154
+ url: 'http://otel-collector:4318/v1/logs',
155
+ })
156
+ )
157
+ );
158
+
159
+ const logger = loggerProvider.getLogger('my-service');
160
+ logger.emit({
161
+ severityText: 'INFO',
162
+ body: 'User logged in',
163
+ attributes: {
164
+ 'user.id': '12345',
165
+ 'http.method': 'POST',
166
+ },
167
+ });
168
+ ```
169
+
170
+ ### Direct Push API
171
+
172
+ Send logs directly to Loki's push endpoint:
173
+
174
+ ```bash
175
+ curl -X POST http://localhost:3100/loki/api/v1/push \
176
+ -H "Content-Type: application/json" \
177
+ -d '{
178
+ "streams": [
179
+ {
180
+ "stream": {
181
+ "service": "my-app",
182
+ "level": "info",
183
+ "environment": "development"
184
+ },
185
+ "values": [
186
+ ["'$(date +%s)000000000'", "User logged in successfully"],
187
+ ["'$(date +%s)000000000'", "Session created"]
188
+ ]
189
+ }
190
+ ]
191
+ }'
192
+ ```
193
+
194
+ **Push format:**
195
+
196
+ - Timestamp in nanoseconds (string)
197
+ - Log line (string)
198
+ - Labels in `stream` object
199
+
200
+ ### Using Promtail (Log Shipper)
201
+
202
+ Promtail tails log files and ships them to Loki:
203
+
204
+ **docker-compose.promtail.yml:**
205
+
206
+ ```yaml
207
+ version: '3.8'
208
+ services:
209
+ promtail:
210
+ image: grafana/promtail:latest
211
+ volumes:
212
+ - /var/log:/var/log:ro
213
+ - ./promtail-config.yaml:/etc/promtail/config.yaml:ro
214
+ command: -config.file=/etc/promtail/config.yaml
215
+ networks:
216
+ - devnet
217
+ depends_on:
218
+ - loki
219
+
220
+ networks:
221
+ devnet:
222
+ name: devnet
223
+ ```
224
+
225
+ **promtail-config.yaml:**
226
+
227
+ ```yaml
228
+ server:
229
+ http_listen_port: 9080
230
+ grpc_listen_port: 0
231
+
232
+ positions:
233
+ filename: /tmp/positions.yaml
234
+
235
+ clients:
236
+ - url: http://loki:3100/loki/api/v1/push
237
+
238
+ scrape_configs:
239
+ - job_name: system
240
+ static_configs:
241
+ - targets:
242
+ - localhost
243
+ labels:
244
+ job: varlogs
245
+ host: devcontainer
246
+ __path__: /var/log/*.log
247
+
248
+ - job_name: application
249
+ static_configs:
250
+ - targets:
251
+ - localhost
252
+ labels:
253
+ job: app
254
+ service: my-app
255
+ __path__: /var/log/app/*.log
256
+ pipeline_stages:
257
+ - json:
258
+ expressions:
259
+ level: level
260
+ timestamp: time
261
+ message: msg
262
+ - labels:
263
+ level:
264
+ - timestamp:
265
+ source: timestamp
266
+ format: RFC3339
267
+ - output:
268
+ source: message
269
+ ```
270
+
271
+ ### Using Docker Logging Driver
272
+
273
+ Send container logs directly to Loki:
274
+
275
+ ```yaml
276
+ # docker-compose.yml
277
+ services:
278
+ my-app:
279
+ image: my-app:latest
280
+ logging:
281
+ driver: loki
282
+ options:
283
+ loki-url: 'http://loki:3100/loki/api/v1/push'
284
+ loki-batch-size: '400'
285
+ loki-retries: '2'
286
+ labels: 'service,environment'
287
+ labels:
288
+ service: 'my-app'
289
+ environment: 'development'
290
+ ```
291
+
292
+ ### Using Application Libraries
293
+
294
+ #### Node.js (Winston + winston-loki)
295
+
296
+ ```bash
297
+ npm install winston winston-loki
298
+ ```
299
+
300
+ ```javascript
301
+ const winston = require('winston');
302
+ const LokiTransport = require('winston-loki');
303
+
304
+ const logger = winston.createLogger({
305
+ transports: [
306
+ new LokiTransport({
307
+ host: 'http://loki:3100',
308
+ labels: {
309
+ service: 'my-app',
310
+ environment: 'development',
311
+ },
312
+ json: true,
313
+ format: winston.format.json(),
314
+ replaceTimestamp: true,
315
+ onConnectionError: (err) => console.error(err),
316
+ }),
317
+ ],
318
+ });
319
+
320
+ logger.info('User logged in', { userId: '12345', method: 'POST' });
321
+ logger.error('Payment failed', { orderId: '67890', error: 'timeout' });
322
+ ```
323
+
324
+ #### Python (python-logging-loki)
325
+
326
+ ```bash
327
+ pip install python-logging-loki
328
+ ```
329
+
330
+ ```python
331
+ import logging
332
+ import logging_loki
333
+
334
+ handler = logging_loki.LokiHandler(
335
+ url="http://loki:3100/loki/api/v1/push",
336
+ tags={"service": "my-app", "environment": "development"},
337
+ version="1",
338
+ )
339
+
340
+ logger = logging.getLogger("my-app")
341
+ logger.addHandler(handler)
342
+ logger.setLevel(logging.INFO)
343
+
344
+ logger.info("User logged in", extra={"user_id": "12345"})
345
+ logger.error("Database connection failed", extra={"db": "postgres", "retry": 3})
346
+ ```
347
+
348
+ #### Go (grafana/loki-client-go)
349
+
350
+ ```bash
351
+ go get github.com/grafana/loki-client-go/loki
352
+ ```
353
+
354
+ ```go
355
+ package main
356
+
357
+ import (
358
+ "github.com/grafana/loki-client-go/loki"
359
+ "github.com/prometheus/common/model"
360
+ )
361
+
362
+ func main() {
363
+ cfg := loki.Config{
364
+ URL: "http://loki:3100",
365
+ }
366
+
367
+ client, err := loki.New(cfg)
368
+ if err != nil {
369
+ panic(err)
370
+ }
371
+ defer client.Stop()
372
+
373
+ labels := model.LabelSet{
374
+ "service": "my-app",
375
+ "environment": "development",
376
+ "level": "info",
377
+ }
378
+
379
+ client.Handle(labels, time.Now(), "User logged in successfully")
380
+ }
381
+ ```
382
+
383
+ ## Querying Logs with LogQL
384
+
385
+ ### Basic Queries
386
+
387
+ **All logs from a service:**
388
+
389
+ ```logql
390
+ {service="my-app"}
391
+ ```
392
+
393
+ **Logs from multiple services:**
394
+
395
+ ```logql
396
+ {service=~"api|web"}
397
+ ```
398
+
399
+ **Exclude specific services:**
400
+
401
+ ```logql
402
+ {service!="health-check"}
403
+ ```
404
+
405
+ **Multiple label filters:**
406
+
407
+ ```logql
408
+ {service="api", environment="production", level="error"}
409
+ ```
410
+
411
+ ### Line Filtering
412
+
413
+ **Logs containing text (case-sensitive):**
414
+
415
+ ```logql
416
+ {service="my-app"} |= "error"
417
+ ```
418
+
419
+ **Logs NOT containing text:**
420
+
421
+ ```logql
422
+ {service="my-app"} != "debug"
423
+ ```
424
+
425
+ **Case-insensitive search:**
426
+
427
+ ```logql
428
+ {service="my-app"} |~ "(?i)error"
429
+ ```
430
+
431
+ **Regex pattern:**
432
+
433
+ ```logql
434
+ {service="my-app"} |~ "user_id=[0-9]+"
435
+ ```
436
+
437
+ **Multiple filters:**
438
+
439
+ ```logql
440
+ {service="my-app"} |= "error" != "timeout" |~ "database"
441
+ ```
442
+
443
+ ### Parsing and Formatting
444
+
445
+ **JSON parsing:**
446
+
447
+ ```logql
448
+ {service="my-app"} | json
449
+ ```
450
+
451
+ **JSON parsing with field extraction:**
452
+
453
+ ```logql
454
+ {service="my-app"} | json | status_code >= 400
455
+ ```
456
+
457
+ **Logfmt parsing:**
458
+
459
+ ```logql
460
+ {service="my-app"} | logfmt | level="error"
461
+ ```
462
+
463
+ **Pattern extraction:**
464
+
465
+ ```logql
466
+ {service="my-app"} | pattern `<ip> - - <_> "<method> <uri> <_>" <status> <_>`
467
+ ```
468
+
469
+ **Regex extraction:**
470
+
471
+ ```logql
472
+ {service="my-app"} | regexp `user_id=(?P<user_id>\d+)`
473
+ ```
474
+
475
+ **Line formatting:**
476
+
477
+ ```logql
478
+ {service="my-app"} | json | line_format "{{.level}}: {{.message}}"
479
+ ```
480
+
481
+ **Label formatting:**
482
+
483
+ ```logql
484
+ {service="my-app"} | json | label_format user="user_{{.user_id}}"
485
+ ```
486
+
487
+ ### Aggregations and Metrics
488
+
489
+ **Count log lines:**
490
+
491
+ ```logql
492
+ count_over_time({service="my-app"}[5m])
493
+ ```
494
+
495
+ **Rate of log lines (per second):**
496
+
497
+ ```logql
498
+ rate({service="my-app"}[5m])
499
+ ```
500
+
501
+ **Sum of extracted values:**
502
+
503
+ ```logql
504
+ sum(rate({service="my-app"} | json | __error__="" [5m]))
505
+ ```
506
+
507
+ **Rate of errors:**
508
+
509
+ ```logql
510
+ sum(rate({service="my-app"} |= "error" [5m]))
511
+ ```
512
+
513
+ **Error ratio:**
514
+
515
+ ```logql
516
+ sum(rate({service="my-app"} |= "error" [5m])) /
517
+ sum(rate({service="my-app"} [5m]))
518
+ ```
519
+
520
+ **Bytes processed:**
521
+
522
+ ```logql
523
+ sum(bytes_over_time({service="my-app"}[5m]))
524
+ ```
525
+
526
+ **Bytes rate:**
527
+
528
+ ```logql
529
+ sum(bytes_rate({service="my-app"}[5m]))
530
+ ```
531
+
532
+ ### Aggregation Functions
533
+
534
+ **Sum by label:**
535
+
536
+ ```logql
537
+ sum by (service) (rate({environment="production"}[5m]))
538
+ ```
539
+
540
+ **Average:**
541
+
542
+ ```logql
543
+ avg(rate({service="my-app"} | json | unwrap response_time [5m]))
544
+ ```
545
+
546
+ **Min/Max:**
547
+
548
+ ```logql
549
+ min(rate({service="my-app"} | json | unwrap duration [5m]))
550
+ max(rate({service="my-app"} | json | unwrap duration [5m]))
551
+ ```
552
+
553
+ **Count distinct:**
554
+
555
+ ```logql
556
+ count(count by (user_id) ({service="my-app"} | json))
557
+ ```
558
+
559
+ **Top K:**
560
+
561
+ ```logql
562
+ topk(10, sum by (endpoint) (rate({service="api"}[5m])))
563
+ ```
564
+
565
+ **Bottom K:**
566
+
567
+ ```logql
568
+ bottomk(5, avg by (service) (rate({environment="production"}[1h])))
569
+ ```
570
+
571
+ ### Advanced Queries
572
+
573
+ **Quantile (percentile):**
574
+
575
+ ```logql
576
+ quantile_over_time(0.95,
577
+ {service="my-app"} | json | unwrap response_time [5m]
578
+ )
579
+ ```
580
+
581
+ **Histogram:**
582
+
583
+ ```logql
584
+ histogram_over_time(
585
+ {service="my-app"} | json | unwrap duration [5m]
586
+ )
587
+ ```
588
+
589
+ **Stddev/Stdvar:**
590
+
591
+ ```logql
592
+ stddev_over_time({service="my-app"} | json | unwrap latency [5m])
593
+ ```
594
+
595
+ **IP filtering:**
596
+
597
+ ```logql
598
+ {service="nginx"}
599
+ | json
600
+ | remote_addr != "127.0.0.1"
601
+ | remote_addr !~ "192.168.*"
602
+ ```
603
+
604
+ **Complex parsing and filtering:**
605
+
606
+ ```logql
607
+ {service="my-app"}
608
+ | json
609
+ | level="error"
610
+ | http_status >= 500
611
+ | duration > 1000
612
+ | line_format "{{.timestamp}} [{{.level}}] {{.message}}"
613
+ ```
614
+
615
+ ## Structured Logging Best Practices
616
+
617
+ ### Node.js (Pino)
618
+
619
+ ```bash
620
+ npm install pino pino-pretty
621
+ ```
622
+
623
+ ```javascript
624
+ const pino = require('pino');
625
+
626
+ const logger = pino({
627
+ level: process.env.LOG_LEVEL || 'info',
628
+ formatters: {
629
+ level: (label) => ({ level: label }),
630
+ },
631
+ base: {
632
+ service: 'my-app',
633
+ environment: process.env.NODE_ENV,
634
+ },
635
+ timestamp: pino.stdTimeFunctions.isoTime,
636
+ });
637
+
638
+ // Structured logging
639
+ logger.info({ userId: '12345', action: 'login', ip: '192.168.1.1' }, 'User logged in successfully');
640
+
641
+ logger.error(
642
+ {
643
+ userId: '12345',
644
+ orderId: '67890',
645
+ error: 'timeout',
646
+ duration: 5000,
647
+ },
648
+ 'Payment processing failed'
649
+ );
650
+
651
+ // With child loggers
652
+ const requestLogger = logger.child({ requestId: 'abc-123' });
653
+ requestLogger.info('Processing request');
654
+ ```
655
+
656
+ ### Python (structlog)
657
+
658
+ ```bash
659
+ pip install structlog
660
+ ```
661
+
662
+ ```python
663
+ import structlog
664
+
665
+ structlog.configure(
666
+ processors=[
667
+ structlog.processors.TimeStamper(fmt="iso"),
668
+ structlog.processors.StackInfoRenderer(),
669
+ structlog.processors.format_exc_info,
670
+ structlog.processors.JSONRenderer()
671
+ ],
672
+ context_class=dict,
673
+ logger_factory=structlog.PrintLoggerFactory(),
674
+ cache_logger_on_first_use=True,
675
+ )
676
+
677
+ logger = structlog.get_logger()
678
+
679
+ # Bind context
680
+ logger = logger.bind(service="my-app", environment="production")
681
+
682
+ # Log with structure
683
+ logger.info(
684
+ "user.login",
685
+ user_id="12345",
686
+ ip="192.168.1.1",
687
+ method="POST"
688
+ )
689
+
690
+ logger.error(
691
+ "payment.failed",
692
+ user_id="12345",
693
+ order_id="67890",
694
+ error="timeout",
695
+ duration_ms=5000
696
+ )
697
+ ```
698
+
699
+ ### .NET (Serilog)
700
+
701
+ ```bash
702
+ dotnet add package Serilog.AspNetCore
703
+ dotnet add package Serilog.Sinks.Console
704
+ dotnet add package Serilog.Formatting.Compact
705
+ ```
706
+
707
+ ```csharp
708
+ using Serilog;
709
+ using Serilog.Formatting.Compact;
710
+
711
+ Log.Logger = new LoggerConfiguration()
712
+ .MinimumLevel.Information()
713
+ .Enrich.WithProperty("Service", "my-app")
714
+ .Enrich.WithProperty("Environment", "production")
715
+ .Enrich.FromLogContext()
716
+ .WriteTo.Console(new CompactJsonFormatter())
717
+ .CreateLogger();
718
+
719
+ // Structured logging
720
+ Log.Information(
721
+ "User {UserId} logged in from {IpAddress}",
722
+ "12345",
723
+ "192.168.1.1"
724
+ );
725
+
726
+ Log.Error(
727
+ "Payment processing failed for order {OrderId}: {Error}",
728
+ "67890",
729
+ "timeout"
730
+ );
731
+
732
+ // With scoped properties
733
+ using (LogContext.PushProperty("RequestId", "abc-123"))
734
+ {
735
+ Log.Information("Processing request");
736
+ }
737
+ ```
738
+
739
+ ### Go (zap)
740
+
741
+ ```bash
742
+ go get go.uber.org/zap
743
+ ```
744
+
745
+ ```go
746
+ package main
747
+
748
+ import "go.uber.org/zap"
749
+
750
+ func main() {
751
+ logger, _ := zap.NewProduction()
752
+ defer logger.Sync()
753
+
754
+ logger = logger.With(
755
+ zap.String("service", "my-app"),
756
+ zap.String("environment", "production"),
757
+ )
758
+
759
+ // Structured logging
760
+ logger.Info("User logged in",
761
+ zap.String("user_id", "12345"),
762
+ zap.String("ip", "192.168.1.1"),
763
+ zap.String("method", "POST"),
764
+ )
765
+
766
+ logger.Error("Payment processing failed",
767
+ zap.String("user_id", "12345"),
768
+ zap.String("order_id", "67890"),
769
+ zap.String("error", "timeout"),
770
+ zap.Int("duration_ms", 5000),
771
+ )
772
+ }
773
+ ```
774
+
775
+ ## Grafana Integration
776
+
777
+ ### Adding Loki Data Source
778
+
779
+ 1. Open Grafana: http://localhost:3000
780
+ 2. Go to **Configuration** → **Data Sources**
781
+ 3. Click **Add data source**
782
+ 4. Select **Loki**
783
+ 5. Set URL: `http://loki:3100`
784
+ 6. Click **Save & Test**
785
+
786
+ ### Exploring Logs in Grafana
787
+
788
+ 1. Click **Explore** (compass icon)
789
+ 2. Select **Loki** data source
790
+ 3. Enter LogQL query
791
+ 4. Adjust time range
792
+ 5. Click **Run query**
793
+
794
+ **Features:**
795
+
796
+ - Live tailing (follow logs in real-time)
797
+ - Log context (view surrounding log lines)
798
+ - Log labels (filter by clicking labels)
799
+ - Share query link
800
+ - Export to dashboard
801
+
802
+ ### Creating Dashboards
803
+
804
+ **Log volume panel:**
805
+
806
+ ```logql
807
+ sum(rate({service="my-app"}[1m]))
808
+ ```
809
+
810
+ **Error rate panel:**
811
+
812
+ ```logql
813
+ sum(rate({service="my-app"} |= "error" [5m]))
814
+ ```
815
+
816
+ **Response time distribution:**
817
+
818
+ ```logql
819
+ histogram_over_time(
820
+ {service="my-app"} | json | unwrap response_time [5m]
821
+ )
822
+ ```
823
+
824
+ ### Alerting on Logs
825
+
826
+ Create an alert rule in Grafana:
827
+
828
+ ```logql
829
+ # Alert if error rate > 10 per minute
830
+ sum(rate({service="my-app"} |= "error" [5m])) > 10
831
+ ```
832
+
833
+ **Alert configuration:**
834
+
835
+ - Evaluation interval: 1m
836
+ - For: 5m (alert after 5 minutes)
837
+ - Notification channel: Slack, email, PagerDuty
838
+
839
+ ## Best Practices
840
+
841
+ ### Label Strategy
842
+
843
+ **✅ Good labels (low cardinality):**
844
+
845
+ ```json
846
+ {
847
+ "service": "api",
848
+ "environment": "production",
849
+ "level": "error",
850
+ "host": "server-1"
851
+ }
852
+ ```
853
+
854
+ **❌ Bad labels (high cardinality):**
855
+
856
+ ```json
857
+ {
858
+ "user_id": "12345", // Millions of unique values
859
+ "request_id": "abc-123", // Every request unique
860
+ "timestamp": "..." // Always unique
861
+ }
862
+ ```
863
+
864
+ **Rule:** Keep total unique label combinations under 100-1000.
865
+
866
+ ### Label vs. Log Content
867
+
868
+ **Use labels for:**
869
+
870
+ - Service identification
871
+ - Environment (dev/staging/prod)
872
+ - Log level (debug/info/warn/error)
873
+ - Component/module
874
+ - Deployment/cluster
875
+
876
+ **Use log content for:**
877
+
878
+ - User IDs, transaction IDs
879
+ - Error messages
880
+ - Detailed context
881
+ - Variable data
882
+ - Metrics to extract
883
+
884
+ ### Log Levels
885
+
886
+ Use consistent levels:
887
+
888
+ ```javascript
889
+ logger.debug({ details: '...' }, 'Detailed debugging');
890
+ logger.info({ user: '123' }, 'Normal operation');
891
+ logger.warn({ threshold: 80 }, 'Warning condition');
892
+ logger.error({ err }, 'Error occurred');
893
+ logger.fatal({ err }, 'Fatal error, exiting');
894
+ ```
895
+
896
+ ### Performance Optimization
897
+
898
+ **Batch log entries:**
899
+
900
+ ```javascript
901
+ // Bad: One network request per log
902
+ logger.info('Log 1');
903
+ logger.info('Log 2');
904
+
905
+ // Good: Batch multiple logs
906
+ const batch = [
907
+ { timestamp: Date.now(), message: 'Log 1' },
908
+ { timestamp: Date.now(), message: 'Log 2' },
909
+ ];
910
+ sendBatch(batch);
911
+ ```
912
+
913
+ **Use appropriate retention:**
914
+
915
+ ```yaml
916
+ limits_config:
917
+ retention_period: 168h # 7 days for dev
918
+ # retention_period: 2160h # 90 days for prod
919
+ ```
920
+
921
+ **Limit log line size:**
922
+
923
+ ```yaml
924
+ limits_config:
925
+ max_line_size: 256000 # 256KB
926
+ ```
927
+
928
+ **Rate limiting:**
929
+
930
+ ```yaml
931
+ limits_config:
932
+ ingestion_rate_mb: 10
933
+ ingestion_burst_size_mb: 20
934
+ ```
935
+
936
+ ## Troubleshooting
937
+
938
+ ### Logs not appearing
939
+
940
+ **Check Loki is running:**
941
+
942
+ ```bash
943
+ docker-compose ps loki
944
+ docker-compose logs loki
945
+ ```
946
+
947
+ **Check Loki health:**
948
+
949
+ ```bash
950
+ curl http://localhost:3100/ready
951
+ # Should return: ready
952
+
953
+ curl http://localhost:3100/metrics
954
+ # Should return Prometheus metrics
955
+ ```
956
+
957
+ **Test push API:**
958
+
959
+ ```bash
960
+ curl -X POST http://localhost:3100/loki/api/v1/push \
961
+ -H "Content-Type: application/json" \
962
+ -d '{
963
+ "streams": [{
964
+ "stream": {"test": "value"},
965
+ "values": [["'$(date +%s)000000000'", "test log"]]
966
+ }]
967
+ }'
968
+ ```
969
+
970
+ **Query for test logs:**
971
+
972
+ ```bash
973
+ curl 'http://localhost:3100/loki/api/v1/query?query={test="value"}'
974
+ ```
975
+
976
+ ### Out of memory
977
+
978
+ **Reduce chunk sizes:**
979
+
980
+ ```yaml
981
+ ingester:
982
+ chunk_block_size: 131072 # 128KB (default 256KB)
983
+ chunk_idle_period: 3m # Flush more frequently
984
+ ```
985
+
986
+ **Enable retention:**
987
+
988
+ ```yaml
989
+ limits_config:
990
+ retention_deletes_enabled: true
991
+ retention_period: 168h # 7 days
992
+ ```
993
+
994
+ **Limit ingestion rate:**
995
+
996
+ ```yaml
997
+ limits_config:
998
+ ingestion_rate_mb: 5 # Reduce from 10
999
+ max_streams_per_user: 5000
1000
+ ```
1001
+
1002
+ **Check memory usage:**
1003
+
1004
+ ```bash
1005
+ docker stats loki
1006
+ ```
1007
+
1008
+ ### Slow queries
1009
+
1010
+ **Add label filters:**
1011
+
1012
+ ```logql
1013
+ # ✅ Good - Specific labels
1014
+ {service="my-app", level="error"}
1015
+
1016
+ # ❌ Bad - No label filters
1017
+ {} |= "error"
1018
+ ```
1019
+
1020
+ **Narrow time range:**
1021
+
1022
+ ```logql
1023
+ # Query last 5 minutes, not last 24 hours
1024
+ {service="my-app"}[5m]
1025
+ ```
1026
+
1027
+ **Avoid expensive parsing:**
1028
+
1029
+ ```logql
1030
+ # ❌ Slow - Parses all lines
1031
+ {service="my-app"} | json | user_id="12345"
1032
+
1033
+ # ✅ Fast - Filter first, then parse
1034
+ {service="my-app"} |= "12345" | json | user_id="12345"
1035
+ ```
1036
+
1037
+ **Use metrics for aggregations:**
1038
+
1039
+ ```logql
1040
+ # For high-volume logs, use Prometheus for metrics
1041
+ # Use Loki for actual log content
1042
+ ```
1043
+
1044
+ ### High cardinality warnings
1045
+
1046
+ **Check stream count:**
1047
+
1048
+ ```bash
1049
+ curl http://localhost:3100/loki/api/v1/streams
1050
+ ```
1051
+
1052
+ **Fix high cardinality:**
1053
+
1054
+ ```yaml
1055
+ # Before (bad):
1056
+ labels:
1057
+ user_id: "12345" # Millions of streams
1058
+ request_id: "abc-123" # Every request creates new stream
1059
+
1060
+ # After (good):
1061
+ labels:
1062
+ service: "my-app" # Few streams
1063
+ level: "info" # Few streams
1064
+ # Move user_id to log content:
1065
+ message: "User 12345 logged in"
1066
+ ```
1067
+
1068
+ **Monitor ingester streams:**
1069
+
1070
+ ```promql
1071
+ loki_ingester_streams
1072
+ ```
1073
+
1074
+ ### Data not persisting
1075
+
1076
+ **Check volume mount:**
1077
+
1078
+ ```bash
1079
+ docker volume ls | grep loki
1080
+ docker volume inspect <loki_volume>
1081
+ ```
1082
+
1083
+ **Verify configuration:**
1084
+
1085
+ ```yaml
1086
+ storage_config:
1087
+ boltdb_shipper:
1088
+ active_index_directory: /loki/index
1089
+ filesystem:
1090
+ directory: /loki/chunks
1091
+ ```
1092
+
1093
+ **Check disk space:**
1094
+
1095
+ ```bash
1096
+ docker-compose exec loki df -h /loki
1097
+ ```
1098
+
1099
+ ## Use Cases
1100
+
1101
+ ### Application Logging
1102
+
1103
+ - Centralized log aggregation from microservices
1104
+ - Error tracking and debugging
1105
+ - Audit trails and compliance logs
1106
+ - Request/response logging
1107
+
1108
+ ### Infrastructure Monitoring
1109
+
1110
+ - System logs (syslog, journald)
1111
+ - Container logs (Docker, Kubernetes)
1112
+ - Network device logs
1113
+ - Security logs
1114
+
1115
+ ### Correlation with Metrics and Traces
1116
+
1117
+ - Link logs to traces via trace ID
1118
+ - Correlate errors with metrics spikes
1119
+ - Debug performance issues
1120
+ - Root cause analysis
1121
+
1122
+ ### Real-time Monitoring
1123
+
1124
+ - Live log tailing in Grafana
1125
+ - Alert on log patterns
1126
+ - Security incident detection
1127
+ - Business event tracking
1128
+
1129
+ ## Related Overlays
1130
+
1131
+ - **grafana** - Visualization and querying interface for Loki
1132
+ - **otel-collector** - Centralized telemetry collection (logs, traces, metrics)
1133
+ - **prometheus** - Metrics correlation with logs
1134
+ - **jaeger** - Trace-log correlation
1135
+ - **nodejs/python/dotnet/go** - Application frameworks with structured logging
1136
+
1137
+ ## Additional Resources
1138
+
1139
+ - [Loki Documentation](https://grafana.com/docs/loki/latest/)
1140
+ - [LogQL Query Language](https://grafana.com/docs/loki/latest/logql/)
1141
+ - [Best Practices](https://grafana.com/docs/loki/latest/best-practices/)
1142
+ - [Promtail Configuration](https://grafana.com/docs/loki/latest/clients/promtail/)
1143
+ - [Loki API](https://grafana.com/docs/loki/latest/api/)
1144
+ - [Label Best Practices](https://grafana.com/docs/loki/latest/best-practices/#labels)
1145
+
1146
+ ## Notes
1147
+
1148
+ - This overlay **requires compose stack** (uses docker-compose)
1149
+ - Loki runs on port **3100** (configurable with port-offset)
1150
+ - Data persists in Docker volume `loki_data`
1151
+ - Default retention is **disabled** (enable in config for auto-cleanup)
1152
+ - Keep label cardinality **low** (< 1000 unique combinations)
1153
+ - Use hostname **`loki`** from other containers
1154
+ - Use **`localhost`** from host machine
1155
+ - Index only labels, not log content (cost-effective storage)
1156
+ - Use **structured logging** for better queryability