|
@@ -7,18 +7,81 @@ metadata:
|
|
|
app: vector
|
|
app: vector
|
|
|
data:
|
|
data:
|
|
|
vector.toml: |
|
|
vector.toml: |
|
|
|
- # Simple Vector config - read and forward Docker logs
|
|
|
|
|
- [sources.docker_logs]
|
|
|
|
|
- type = "file"
|
|
|
|
|
- include = ["/var/lib/docker/containers/*/*-json.log"]
|
|
|
|
|
|
|
+ [sources.kubernetes_logs]
|
|
|
|
|
+ type = "kubernetes_logs"
|
|
|
|
|
+ read_from = "beginning"
|
|
|
|
|
+ fingerprint_lines = 0
|
|
|
|
|
+ max_read_bytes = 262144
|
|
|
|
|
+ glob_minimum_cooldown_ms = 100
|
|
|
|
|
+ max_line_bytes = 102400
|
|
|
|
|
+ ignore_older_secs = 0
|
|
|
data_dir = "/var/lib/vector"
|
|
data_dir = "/var/lib/vector"
|
|
|
|
|
|
|
|
- # Send directly to Loki without transformations
|
|
|
|
|
|
|
+ [transforms.parse_and_enrich]
|
|
|
|
|
+ type = "remap"
|
|
|
|
|
+ inputs = ["kubernetes_logs"]
|
|
|
|
|
+ drop_on_abort = false
|
|
|
|
|
+ source = """
|
|
|
|
|
+ # Extract Kubernetes metadata
|
|
|
|
|
+ .pod_name = .kubernetes.pod_name
|
|
|
|
|
+ .namespace = .kubernetes.namespace_name
|
|
|
|
|
+ .container = .kubernetes.container_name
|
|
|
|
|
+
|
|
|
|
|
+ # Initialize app with unknown
|
|
|
|
|
+ .app = "unknown"
|
|
|
|
|
+
|
|
|
|
|
+ # Debug trace fields
|
|
|
|
|
+ .debug_pod = .kubernetes.pod_name
|
|
|
|
|
+ .debug_k8s_label_app = .kubernetes.labels.app
|
|
|
|
|
+
|
|
|
|
|
+ # Check if this is a JSON log (Java/Logstash format with nested JSON)
|
|
|
|
|
+ if exists(.log) {
|
|
|
|
|
+ log_str = string!(.log)
|
|
|
|
|
+ .debug_log_length = length(log_str)
|
|
|
|
|
+ .debug_has_timestamp = contains(log_str, "@timestamp")
|
|
|
|
|
+
|
|
|
|
|
+ if contains(log_str, "@timestamp") {
|
|
|
|
|
+ # Try to parse the nested JSON
|
|
|
|
|
+ parsed = parse_json(log_str) ?? null
|
|
|
|
|
+ if parsed != null {
|
|
|
|
|
+ .debug_parse_success = true
|
|
|
|
|
+ if exists(parsed.app) {
|
|
|
|
|
+ .app = parsed.app
|
|
|
|
|
+ .debug_source = "parsed_json"
|
|
|
|
|
+ .debug_parsed_app = parsed.app
|
|
|
|
|
+ } else {
|
|
|
|
|
+ .debug_parse_no_app = "app_field_missing_in_parsed_json"
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ .debug_parse_success = false
|
|
|
|
|
+ .debug_parse_error = "parse_json_returned_null"
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ .debug_no_timestamp = "log_does_not_contain_@timestamp"
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ # Fallback to Kubernetes labels if we still don't have app name
|
|
|
|
|
+ if .app == "unknown" && exists(.kubernetes.labels.app) {
|
|
|
|
|
+ .app = .kubernetes.labels.app
|
|
|
|
|
+ .debug_source = "k8s_labels"
|
|
|
|
|
+ .debug_fallback_app = .kubernetes.labels.app
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .debug_final_app = .app
|
|
|
|
|
+ .env = "kubernetes"
|
|
|
|
|
+ """
|
|
|
|
|
+
|
|
|
[sinks.loki]
|
|
[sinks.loki]
|
|
|
type = "loki"
|
|
type = "loki"
|
|
|
- inputs = ["docker_logs"]
|
|
|
|
|
|
|
+ inputs = ["parse_and_enrich"]
|
|
|
endpoint = "{{ .Values.vector.loki.endpoint }}"
|
|
endpoint = "{{ .Values.vector.loki.endpoint }}"
|
|
|
- [sinks.loki.encoding]
|
|
|
|
|
- codec = "json"
|
|
|
|
|
|
|
+ encoding.codec = "json"
|
|
|
|
|
+ buffer.type = "memory"
|
|
|
|
|
+ buffer.max_events = 10000
|
|
|
|
|
+ # Use only templating for labels - Vector Loki sink needs raw field access
|
|
|
[sinks.loki.labels]
|
|
[sinks.loki.labels]
|
|
|
- environment = "docker"
|
|
|
|
|
|
|
+ namespace = "{{ namespace }}"
|
|
|
|
|
+ app = "{{ app }}"
|
|
|
|
|
+ pod = "{{ pod_name }}"
|
|
|
|
|
+ container = "{{ container }}"
|