Skip to content

Commit 63f8926

Browse files
authored
Merge pull request #64 from eranra/add_loki
initial loki integration
2 parents b292799 + 00f8f8b commit 63f8926

27 files changed

+1321
-34
lines changed

Makefile

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,21 @@ undeploy: ## Undeploy the image
124124
kubectl --ignore-not-found=true delete configmap flowlogs2metrics-configuration || true
125125
kubectl --ignore-not-found=true delete -f /tmp/deployment.yaml || true
126126

127+
.PHONY: deploy-loki
128+
deploy-loki: ## Deploy loki
129+
kubectl apply -f contrib/kubernetes/deployment-loki-storage.yaml
130+
kubectl apply -f contrib/kubernetes/deployment-loki.yaml
131+
kubectl rollout status "deploy/loki" --timeout=600s
132+
-pkill --oldest --full "3100:3100"
133+
kubectl port-forward --address 0.0.0.0 svc/loki 3100:3100 2>&1 >/dev/null &
134+
@echo -e "\nloki endpoint is available on http://localhost:3100\n"
135+
136+
.PHONY: undeploy-loki
137+
undeploy-loki: ## Undeploy loki
138+
kubectl --ignore-not-found=true delete -f contrib/kubernetes/deployment-loki.yaml || true
139+
kubectl --ignore-not-found=true delete -f contrib/kubernetes/deployment-loki-storage.yaml || true
140+
-pkill --oldest --full "3100:3100"
141+
127142
.PHONY: deploy-prometheus
128143
deploy-prometheus: ## Deploy prometheus
129144
kubectl apply -f contrib/kubernetes/deployment-prometheus.yaml
@@ -185,7 +200,7 @@ generate-configuration: $(KIND) ## Generate metrics configuration
185200
##@ End2End
186201

187202
.PHONY: local-deployments-deploy
188-
local-deployments-deploy: $(KIND) deploy-prometheus deploy-grafana deploy deploy-netflow-simulator
203+
local-deployments-deploy: $(KIND) deploy-prometheus deploy-loki deploy-grafana deploy deploy-netflow-simulator
189204
kubectl get pods
190205
kubectl rollout status -w deployment/flowlogs2metrics
191206
kubectl logs -l app=flowlogs2metrics
@@ -194,7 +209,7 @@ local-deployments-deploy: $(KIND) deploy-prometheus deploy-grafana deploy deploy
194209
local-deploy: $(KIND) local-cleanup create-kind-cluster local-deployments-deploy ## Deploy locally on kind (with simulated flowlogs)
195210

196211
.PHONY: local-deployments-cleanup
197-
local-deployments-cleanup: $(KIND) undeploy-netflow-simulator undeploy undeploy-grafana undeploy-prometheus
212+
local-deployments-cleanup: $(KIND) undeploy-netflow-simulator undeploy undeploy-grafana undeploy-loki undeploy-prometheus
198213

199214
.PHONY: local-cleanup
200215
local-cleanup: $(KIND) local-deployments-cleanup delete-kind-cluster ## Undeploy from local kind
@@ -203,7 +218,7 @@ local-cleanup: $(KIND) local-deployments-cleanup delete-kind-cluster ## Undeploy
203218
local-redeploy: local-deployments-cleanup local-deployments-deploy ## Redeploy locally (on current kind)
204219

205220
.PHONY: ocp-deploy
206-
ocp-deploy: ocp-cleanup deploy-prometheus deploy-grafana deploy ## Deploy to OCP
221+
ocp-deploy: ocp-cleanup deploy-prometheus deploy-loki deploy-grafana deploy ## Deploy to OCP
207222
flowlogs2metrics_svc_ip=$$(kubectl get svc flowlogs2metrics -o jsonpath='{.spec.clusterIP}'); \
208223
./hack/enable-ocp-flow-export.sh $$flowlogs2metrics_svc_ip
209224
kubectl get pods
@@ -215,9 +230,12 @@ ocp-deploy: ocp-cleanup deploy-prometheus deploy-grafana deploy ## Deploy to OCP
215230
oc expose service grafana || true
216231
@grafana_url=$$(oc get route grafana -o jsonpath='{.spec.host}'); \
217232
echo -e "\nAccess grafana on OCP using: http://"$$grafana_url"\n"
233+
oc expose service loki || true
234+
@loki_url=$$(oc get route loki -o jsonpath='{.spec.host}'); \
235+
echo -e "\nAccess loki on OCP using: http://"$$loki_url"\n"
218236

219237
.PHONY: ocp-cleanup
220-
ocp-cleanup: undeploy undeploy-prometheus undeploy-grafana ## Undeploy from OCP
238+
ocp-cleanup: undeploy undeploy-loki undeploy-prometheus undeploy-grafana ## Undeploy from OCP
221239

222240
.PHONY: dev-local-deploy
223241
dev-local-deploy: ## Deploy locally with simulated netflows

README.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Flags:
4545
--pipeline.ingest.file.filename string Ingest filename (file)
4646
--pipeline.ingest.type string Ingest type: file, collector,file_loop (required)
4747
--pipeline.transform string Transforms (list) API (default "[{"type": "none"}]")
48+
--pipeline.write.loki string Loki write API
4849
--pipeline.write.type string Write type: stdout, none (default "none")
4950
```
5051
<!---END-AUTO-flowlogs2metrics_help--->
@@ -115,9 +116,9 @@ The pipeline is constructed of a sequence of stages:
115116
- **ingest** - obtain flows from some source, one entry per line
116117
- **decode** - parse input lines into a known format, e.g., dictionary (map) of AWS or goflow data
117118
- **transform** - convert entries into a standard format; can include multiple transform stages
119+
- **write** - provide the means to write the data to some target, e.g. loki, standard output, etc
118120
- **extract** - derive a set of metrics from the imported flows
119121
- **encode** - make the data available in appropriate format (e.g. prometheus)
120-
- **write** - provide the means to transfer the data to some target, e.g. prometheus, object store, standard output, etc
121122

122123
The **encode** and **write** stages may be combined in some cases (as in prometheus), in which case **write** is set to **none**
123124

@@ -398,6 +399,34 @@ The name of the prometheus gauge is set to `test_Bytes` by concatenating the pre
398399
The `packets` metric is very similar. It makes use of the `counter` prometheus type which adds reported values
399400
to prometheus counter.
400401

402+
### Loki writer
403+
404+
The loki writer persist flow-logs into [Loki](https://github.com/grafana/loki). The flow-logs are sent with defined
405+
tenant ID and with a set static labels and dynamic labels from the record fields.
406+
For example, sending flow-logs into tenant `theTenant` with labels
407+
from `foo` and `bar` fields
408+
and including static label with key `job` with value `flowlogs2metrics`.
409+
Additional parameters such as `url` and `batchWait` are defined in
410+
Loki writer API [docs/api.md](docs/api.md)
411+
412+
```bash
413+
pipeline:
414+
write:
415+
type: loki
416+
loki:
417+
tenantID: theTenant
418+
loki:
419+
url: http://loki.default.svc.cluster.local:3100
420+
staticLabels:
421+
job: flowlogs2metrics
422+
batchWait: 1m
423+
labels:
424+
- foo
425+
- bar
426+
```
427+
428+
> Note: to view loki flow-logs in `grafana`:: Use the `Explore` tab and choose the `loki` datasource. In the `Log Browser` enter `{job="flowlogs2metrics"}` and press `Run query`
429+
401430
# Development
402431

403432
## Build
@@ -436,6 +465,8 @@ Docker
436465
kubernetes
437466
deploy Deploy the image
438467
undeploy Undeploy the image
468+
deploy-loki Deploy loki
469+
undeploy-loki Undeploy loki
439470
deploy-prometheus Deploy prometheus
440471
undeploy-prometheus Undeploy prometheus
441472
deploy-grafana Deploy grafana

cmd/apitodoc/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ func iterate(output io.Writer, data interface{}, indent int) {
4242
val := reflect.Indirect(reflect.ValueOf(data))
4343
// fieldName := val.Type().Field(i).Name
4444
fieldName := val.Type().Field(i).Tag.Get(api.TagYaml)
45+
fieldName = strings.ReplaceAll(fieldName, ",omitempty", "")
46+
4547
fieldDocTag := val.Type().Field(i).Tag.Get(api.TagDoc)
4648
fieldEnumTag := val.Type().Field(i).Tag.Get(api.TagEnum)
4749

cmd/flowlogs2metrics/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ func initFlags() {
137137
rootCmd.PersistentFlags().StringVar(&config.Opt.PipeLine.Extract.Aggregates, "pipeline.extract.aggregates", "", "Aggregates (see docs)")
138138
rootCmd.PersistentFlags().StringVar(&config.Opt.PipeLine.Encode.Type, "pipeline.encode.type", "none", "Encode type: prom, none")
139139
rootCmd.PersistentFlags().StringVar(&config.Opt.PipeLine.Write.Type, "pipeline.write.type", "none", "Write type: stdout, none")
140+
rootCmd.PersistentFlags().StringVar(&config.Opt.PipeLine.Write.Loki, "pipeline.write.loki", "", "Loki write API")
140141
rootCmd.PersistentFlags().StringVar(&config.Opt.PipeLine.Encode.Prom, "pipeline.encode.prom", "", "Prometheus encode API")
141142

142143
_ = rootCmd.MarkPersistentFlagRequired("pipeline.ingest.type")

contrib/dashboards/dashboard_manual_locations_on_map.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,12 @@
160160
"refresh": "",
161161
"schemaVersion": 34,
162162
"style": "dark",
163-
"tags": [],
163+
"tags": [
164+
"fl2m",
165+
"location",
166+
"map",
167+
"dashboard"
168+
],
164169
"templating": {
165170
"list": []
166171
},
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"annotations": {
3+
"list": [
4+
{
5+
"builtIn": 1,
6+
"datasource": "loki",
7+
"enable": true,
8+
"hide": true,
9+
"iconColor": "rgba(0, 211, 255, 1)",
10+
"name": "Annotations & Alerts",
11+
"target": {
12+
"limit": 100,
13+
"matchAny": false,
14+
"tags": [],
15+
"type": "dashboard"
16+
},
17+
"type": "dashboard"
18+
}
19+
]
20+
},
21+
"editable": true,
22+
"fiscalYearStartMonth": 0,
23+
"graphTooltip": 0,
24+
"id": 4,
25+
"links": [],
26+
"liveNow": false,
27+
"panels": [
28+
{
29+
"datasource": {
30+
"type": "loki",
31+
"uid": "P982945308D3682D1"
32+
},
33+
"description": "Logs from Loki ",
34+
"gridPos": {
35+
"h": 23,
36+
"w": 24,
37+
"x": 0,
38+
"y": 0
39+
},
40+
"id": 2,
41+
"options": {
42+
"dedupStrategy": "none",
43+
"enableLogDetails": true,
44+
"prettifyLogMessage": false,
45+
"showCommonLabels": false,
46+
"showLabels": false,
47+
"showTime": true,
48+
"sortOrder": "Descending",
49+
"wrapLogMessage": false
50+
},
51+
"pluginVersion": "8.3.6",
52+
"targets": [
53+
{
54+
"datasource": {
55+
"type": "loki",
56+
"uid": "P982945308D3682D1"
57+
},
58+
"expr": "{job=\"flowlogs2metrics\"}",
59+
"instant": false,
60+
"range": true,
61+
"refId": "A"
62+
}
63+
],
64+
"title": "Logs",
65+
"type": "logs"
66+
}
67+
],
68+
"refresh": "",
69+
"schemaVersion": 34,
70+
"style": "dark",
71+
"tags": [
72+
"fl2m",
73+
"loki",
74+
"dashboard"
75+
],
76+
"templating": {
77+
"list": []
78+
},
79+
"time": {
80+
"from": "now-5m",
81+
"to": "now"
82+
},
83+
"timepicker": {},
84+
"timezone": "",
85+
"title": "Loki",
86+
"uid": "R-LPqRfnk",
87+
"version": 2,
88+
"weekStart": ""
89+
}

contrib/kubernetes/deployment-grafana.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ data:
6868
type: prometheus
6969
url: http://prometheus.default.svc.cluster.local:9090
7070
version: 1
71+
- access: proxy
72+
isDefault: false
73+
name: loki
74+
type: loki
75+
url: http://loki.default.svc.cluster.local:3100
76+
version: 1
7177
---
7278
apiVersion: v1
7379
kind: ConfigMap
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
apiVersion: v1
3+
kind: PersistentVolumeClaim
4+
metadata:
5+
name: loki-store
6+
spec:
7+
resources:
8+
requests:
9+
storage: 1G
10+
volumeMode: Filesystem
11+
accessModes:
12+
- ReadWriteOnce
13+
---
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: loki-config
6+
data:
7+
local-config.yaml: |
8+
auth_enabled: false
9+
server:
10+
http_listen_port: 3100
11+
grpc_listen_port: 9096
12+
common:
13+
path_prefix: /loki-store
14+
storage:
15+
filesystem:
16+
chunks_directory: /loki-store/chunks
17+
rules_directory: /loki-store/rules
18+
replication_factor: 1
19+
ring:
20+
instance_addr: 127.0.0.1
21+
kvstore:
22+
store: inmemory
23+
schema_config:
24+
configs:
25+
- from: 2020-10-24
26+
store: boltdb-shipper
27+
object_store: filesystem
28+
schema: v11
29+
index:
30+
prefix: index_
31+
period: 24h
32+
storage_config:
33+
filesystem:
34+
directory: /loki-store/storage
35+
boltdb_shipper:
36+
active_index_directory: /loki-store/index
37+
shared_store: filesystem
38+
cache_location: /loki-store/boltdb-cache
39+
---
40+
apiVersion: apps/v1
41+
kind: Deployment
42+
metadata:
43+
name: loki
44+
labels:
45+
app: loki
46+
spec:
47+
replicas: 1
48+
selector:
49+
matchLabels:
50+
app: loki
51+
template:
52+
metadata:
53+
labels:
54+
app: loki
55+
spec:
56+
securityContext:
57+
runAsGroup: 1000
58+
runAsUser: 1000
59+
fsGroup: 1000
60+
containers:
61+
- name: loki
62+
image: grafana/loki:2.4.1
63+
ports:
64+
- containerPort: 3100
65+
imagePullPolicy: Always
66+
volumeMounts:
67+
- mountPath: "/loki-store"
68+
name: loki-store
69+
- mountPath: "/etc/loki"
70+
name: loki-config
71+
volumes:
72+
- name: loki-store
73+
persistentVolumeClaim:
74+
claimName: loki-store
75+
- name: loki-config
76+
configMap:
77+
name: loki-config
78+
---
79+
apiVersion: v1
80+
kind: Service
81+
metadata:
82+
name: loki
83+
labels:
84+
app: loki
85+
spec:
86+
selector:
87+
app: loki
88+
ports:
89+
- port: 3100
90+
targetPort: 3100
91+
name: endpoint
92+
---

contrib/kubernetes/flowlogs2metrics.conf.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,5 +266,9 @@ pipeline:
266266
parameters: '>=512'
267267
type: network
268268
write:
269-
type: none
269+
loki:
270+
url: http://loki.default.svc.cluster.local:3100
271+
staticLabels:
272+
job: flowlogs2metrics
273+
type: loki
270274

0 commit comments

Comments
 (0)