368 lines
17 KiB
TOML
368 lines
17 KiB
TOML
###############################################################################
|
|
### LogWisp Configuration
|
|
### Default location: ~/.config/logwisp/logwisp.toml
|
|
### Precedence: CLI flags > Environment > File > Defaults
|
|
###
|
|
### Commented values are the built-in defaults unless marked "example".
|
|
### Uncommenting a default is a no-op.
|
|
###
|
|
### NOTE: password/token/SCRAM authentication, network access control (ACL),
|
|
### http/tcp ingest sources, and http_client/tcp_client sinks were removed in
|
|
### the restructure and are not available in this version. TLS and mTLS ARE
|
|
### available on every network source and sink; see the [...tls] blocks below,
|
|
### and the [...auth] blocks to authorize peers by certificate identity.
|
|
###
|
|
### Environment overrides are currently read WITHOUT the LOGWISP_ prefix
|
|
### (QUIET, LOGGING_LEVEL, ...). LOGWISP_CONFIG_FILE and LOGWISP_CONFIG_DIR
|
|
### are the exceptions and do carry it. Array-indexed paths such as
|
|
### pipelines.0.name cannot be set from the CLI or environment at all.
|
|
###############################################################################
|
|
|
|
###############################################################################
|
|
### Global Settings
|
|
###############################################################################
|
|
|
|
quiet = false # Suppress console output
|
|
status_reporter = true # Periodic status logging (30s, DEBUG level)
|
|
auto_reload = false # Config auto-reload on file change
|
|
|
|
###############################################################################
|
|
### Logging (LogWisp's internal operational logging)
|
|
###############################################################################
|
|
|
|
[logging]
|
|
output = "stdout" # file|stdout|stderr|split|all|none
|
|
level = "info" # debug|info|warn|error
|
|
# format = "txt" # raw|txt|json
|
|
# sanitization = "" # raw|json|txt|shell (empty = logger default)
|
|
|
|
# [logging.file] # Used when output is "file" or "all"
|
|
# directory = "./log"
|
|
# name = "logwisp"
|
|
# max_size_mb = 100
|
|
# max_total_size_mb = 1000
|
|
# retention_hours = 168.0 # 7 days
|
|
|
|
## Validated but NOT applied: the console destination comes from `output` above.
|
|
# [logging.console]
|
|
# target = "stdout" # stdout|stderr|split
|
|
|
|
###############################################################################
|
|
### Pipelines
|
|
### Each pipeline: plugin_sources -> flow (rate_limit|filters|format) -> plugin_sinks
|
|
### Names must be unique. 1+ source and 1+ sink required.
|
|
###############################################################################
|
|
|
|
[[pipelines]]
|
|
name = "default"
|
|
|
|
###============================================================================
|
|
### Flow (processing between sources and sinks)
|
|
###============================================================================
|
|
|
|
## policy="pass" short-circuits the size check too: enforcing a size cap needs
|
|
## rate > 0 AND policy = "drop".
|
|
# [pipelines.flow.rate_limit]
|
|
# rate = 0.0 # Entries/second (0 = limiter disabled)
|
|
# burst = 0.0 # Burst capacity (defaults to rate)
|
|
# policy = "pass" # pass|drop
|
|
# max_entry_size_bytes = 0 # 0 = unlimited
|
|
|
|
## Filters: sequential include/exclude chain, matched against "<source> <level> <message>"
|
|
# [[pipelines.flow.filters]]
|
|
# type = "include" # include|exclude
|
|
# logic = "or" # or|and
|
|
# patterns = [".*ERROR.*", ".*WARN.*"] # example; RE2 syntax
|
|
|
|
# [pipelines.flow.format]
|
|
# type = "raw" # raw|json|txt
|
|
# flags = 0 # Formatter flags (0 = defaults per type)
|
|
# timestamp_format = "" # Go time layout (formatter default if empty)
|
|
# sanitizer_policy = "" # raw|json|txt|shell (defaults per type)
|
|
|
|
## Flow-level heartbeat (fan-out to all sinks, traverses chain links)
|
|
# [pipelines.flow.heartbeat]
|
|
# enabled = false
|
|
# interval_ms = 1000 # Minimum 100
|
|
# include_timestamp = false
|
|
# include_stats = false
|
|
# format = "txt" # txt|json|raw ("comment" is rejected)
|
|
|
|
###============================================================================
|
|
### TLS (shared shape; applies to every network source and sink)
|
|
###
|
|
### Listeners (tcp/http sinks, tcp_chain/http_chain sources):
|
|
### cert_file + key_file are REQUIRED; client_auth + client_ca_file enable mTLS.
|
|
### Dialers (tcp_chain/http_chain sinks):
|
|
### ca_file + server_name verify the server; cert_file + key_file present a
|
|
### client identity for mTLS.
|
|
###
|
|
### enabled = false Master switch
|
|
### cert_file = "" Local certificate
|
|
### key_file = "" Private key for cert_file (set together)
|
|
### client_auth = false Listener: require and verify a client certificate
|
|
### client_ca_file = "" Listener: CA bundle verifying client certs
|
|
### ca_file = "" Dialer: CA bundle verifying the server (empty = system)
|
|
### server_name = "" Dialer: SNI / name to verify (empty = configured host)
|
|
### insecure_skip_verify = false Dialer: disable verification (never in prod)
|
|
### min_version = "1.3" "1.2" or "1.3". No max_version, no cipher_suites.
|
|
###
|
|
### TLS alone is a CA membership check: ANY certificate the CA signed is
|
|
### accepted. Add an [...auth] block to decide WHICH of them may connect.
|
|
###============================================================================
|
|
|
|
###============================================================================
|
|
### AUTH (shared shape; sits beside [...tls] on every network source and sink)
|
|
###
|
|
### Listeners (tcp/http sinks, tcp_chain/http_chain sources):
|
|
### authorize the client certificate. type = "mtls" REQUIRES tls.enabled and
|
|
### tls.client_auth. On the http sink it gates stream_path AND status_path.
|
|
### Chain sources additionally bind the node label to the identity.
|
|
### Dialers (tcp_chain/http_chain sinks):
|
|
### pin the server identity. type = "mtls" REQUIRES tls.enabled and forbids
|
|
### tls.insecure_skip_verify.
|
|
###
|
|
### type = "none" none | mtls
|
|
### identity = "cn" cn | san_dns | san_uri | san_email
|
|
### allow = [] Exact identities. Empty allow AND allow_patterns
|
|
### admits any identity the CA vouches for (logged WARN).
|
|
### allow_patterns = [] RE2 patterns; anchor them yourself (^...$)
|
|
### node_binding = "" Chain sources only, default "force" under mtls:
|
|
### none - trust_node governs, as before
|
|
### assert - declared label must equal the identity;
|
|
### per-entry node labels still follow trust_node
|
|
### force - label AND every entry take the identity
|
|
### Overrides trust_node. See doc/security.md.
|
|
###============================================================================
|
|
|
|
###============================================================================
|
|
### Sources (1+ required)
|
|
###============================================================================
|
|
|
|
## Null source (testing)
|
|
# [[pipelines.plugin_sources]]
|
|
# id = "null_in"
|
|
# type = "null"
|
|
|
|
[[pipelines.plugin_sources]]
|
|
id = "default_source"
|
|
type = "file"
|
|
[pipelines.plugin_sources.config]
|
|
directory = "./" # Directory to monitor (required, not recursive)
|
|
pattern = "*.log" # Glob pattern (* and ? only)
|
|
## Tailing an already-open file polls at a fixed 100ms, regardless of this value.
|
|
check_interval_ms = 100 # Directory rescan interval (min 10)
|
|
## raw = true never parses a line; with format type "raw" the file is relayed byte for byte.
|
|
raw = false # Keep the whole line as the message
|
|
from = "end" # "end" or "start" of a newly discovered file
|
|
|
|
## Console source (stdin, single instance per pipeline)
|
|
# [[pipelines.plugin_sources]]
|
|
# id = "console_in"
|
|
# type = "console"
|
|
# [pipelines.plugin_sources.config]
|
|
# buffer_size = 1000
|
|
|
|
## Random source (testing; special=true exercises sanitizer policies)
|
|
# [[pipelines.plugin_sources]]
|
|
# id = "random_in"
|
|
# type = "random"
|
|
# [pipelines.plugin_sources.config]
|
|
# interval_ms = 500
|
|
# jitter_ms = 0 # Clamped to interval_ms
|
|
# format = "txt" # raw|txt|json
|
|
# length = 20
|
|
# special = false
|
|
|
|
## TCP chain source (stdlib listener; receives NDJSON from upstream tcp_chain sinks)
|
|
## Topology: jail [file source -> tcp_chain sink] -> host [tcp_chain source -> aggregate sink]
|
|
# [[pipelines.plugin_sources]]
|
|
# id = "chain_in"
|
|
# type = "tcp_chain"
|
|
# [pipelines.plugin_sources.config]
|
|
# host = "0.0.0.0" # IPv4 only
|
|
# port = 9440 # Required
|
|
# buffer_size = 1000
|
|
# max_connections = 0 # 0 = unlimited
|
|
# read_timeout_ms = 0 # idle deadline, 0 = none
|
|
# hello_timeout_ms = 10000 # Protocol preamble deadline
|
|
# trust_node = true # false: label entries by remote address
|
|
# [pipelines.plugin_sources.config.tls]
|
|
# enabled = true # example: mTLS listener
|
|
# cert_file = "/etc/logwisp/tls/server.crt"
|
|
# key_file = "/etc/logwisp/tls/server.key"
|
|
# client_auth = true
|
|
# client_ca_file = "/etc/logwisp/tls/client-ca.crt"
|
|
# min_version = "1.3"
|
|
# [pipelines.plugin_sources.config.auth] # authorize senders by certificate
|
|
# type = "none" # none | mtls; mtls requires client_auth
|
|
# identity = "cn" # cn | san_dns | san_uri | san_email
|
|
# allow = [] # exact identities; empty = any the CA issued
|
|
# allow_patterns = [] # RE2, anchor them yourself
|
|
# node_binding = "force" # none | assert | force; overrides trust_node
|
|
|
|
## HTTP chain source (stdlib listener; receives NDJSON batches from upstream http_chain sinks)
|
|
# [[pipelines.plugin_sources]]
|
|
# id = "hchain_in"
|
|
# type = "http_chain"
|
|
# [pipelines.plugin_sources.config]
|
|
# host = "0.0.0.0"
|
|
# port = 9441 # Required
|
|
# ingest_path = "/ingest" # Must start with "/"
|
|
# buffer_size = 1000
|
|
# max_body_bytes = 8388608 # per-request cap (8 MiB)
|
|
# read_timeout_ms = 30000
|
|
# trust_node = true # false: label entries by remote address
|
|
# [pipelines.plugin_sources.config.tls]
|
|
# enabled = true # example: mTLS listener
|
|
# cert_file = "/etc/logwisp/tls/server.crt"
|
|
# key_file = "/etc/logwisp/tls/server.key"
|
|
# client_auth = true
|
|
# client_ca_file = "/etc/logwisp/tls/client-ca.crt"
|
|
# [pipelines.plugin_sources.config.auth] # authorize senders by certificate
|
|
# type = "none" # none | mtls; mtls requires client_auth
|
|
# identity = "cn" # cn | san_dns | san_uri | san_email
|
|
# allow = [] # exact identities; empty = any the CA issued
|
|
# allow_patterns = [] # RE2, anchor them yourself
|
|
# node_binding = "force" # none | assert | force; overrides trust_node
|
|
|
|
###============================================================================
|
|
### Sinks (1+ required, fan-out)
|
|
###============================================================================
|
|
|
|
## Null sink (testing)
|
|
# [[pipelines.plugin_sinks]]
|
|
# id = "null_out"
|
|
# type = "null"
|
|
|
|
[[pipelines.plugin_sinks]]
|
|
id = "default_sink"
|
|
type = "console"
|
|
[pipelines.plugin_sinks.config]
|
|
target = "stdout" # stdout|stderr ("split" NOT supported)
|
|
# buffer_size = 1000
|
|
|
|
## File sink (rotating)
|
|
# [[pipelines.plugin_sinks]]
|
|
# id = "file_out"
|
|
# type = "file"
|
|
# [pipelines.plugin_sinks.config]
|
|
# directory = "./logs" # Required
|
|
# name = "output" # Required
|
|
# max_size_mb = 100
|
|
# max_total_size_mb = 1000
|
|
# min_disk_free_mb = 0 # 0 = no floor (only negatives become 100)
|
|
# retention_hours = 168.0
|
|
# buffer_size = 1000
|
|
# flush_interval_ms = 100
|
|
|
|
## HTTP sink (SSE streaming server + JSON status endpoint; IPv4 clients only)
|
|
## Both endpoints are UNAUTHENTICATED and the stream sends
|
|
## Access-Control-Allow-Origin: *. Bind to a trusted interface.
|
|
# [[pipelines.plugin_sinks]]
|
|
# id = "http_out"
|
|
# type = "http"
|
|
# [pipelines.plugin_sinks.config]
|
|
# host = "0.0.0.0"
|
|
# port = 8081 # Required
|
|
# stream_path = "/stream" # Must start with "/"
|
|
# status_path = "/status" # Must differ from stream_path
|
|
# buffer_size = 1000 # Sink input queue
|
|
# client_buffer_size = 256 # Per-client send queue
|
|
# write_timeout_ms = 0 # Per-event deadline, 0 = none
|
|
# max_connections = 0 # 0 = unlimited
|
|
# [pipelines.plugin_sinks.config.tls]
|
|
# enabled = true # example
|
|
# cert_file = "/etc/logwisp/tls/server.crt"
|
|
# key_file = "/etc/logwisp/tls/server.key"
|
|
# client_auth = false
|
|
# client_ca_file = ""
|
|
# [pipelines.plugin_sinks.config.auth] # gates BOTH stream_path and status_path
|
|
# type = "none" # none | mtls; mtls requires client_auth
|
|
# identity = "cn" # cn | san_dns | san_uri | san_email
|
|
# allow = [] # exact identities; empty = any the CA issued
|
|
# allow_patterns = [] # RE2, anchor them yourself
|
|
|
|
## TCP sink (streaming server, IPv4 clients only)
|
|
# [[pipelines.plugin_sinks]]
|
|
# id = "tcp_out"
|
|
# type = "tcp"
|
|
# [pipelines.plugin_sinks.config]
|
|
# host = "0.0.0.0"
|
|
# port = 9090 # Required
|
|
# buffer_size = 1000
|
|
# client_buffer_size = 256
|
|
# write_timeout_ms = 5000 # Missed deadline disconnects the client
|
|
# keep_alive = true
|
|
# keep_alive_period_ms = 30000
|
|
# max_connections = 0
|
|
# [pipelines.plugin_sinks.config.tls]
|
|
# enabled = true # example
|
|
# cert_file = "/etc/logwisp/tls/server.crt"
|
|
# key_file = "/etc/logwisp/tls/server.key"
|
|
# client_auth = true
|
|
# client_ca_file = "/etc/logwisp/tls/client-ca.crt"
|
|
# [pipelines.plugin_sinks.config.auth] # authorize stream readers
|
|
# type = "none" # none | mtls; mtls requires client_auth
|
|
# identity = "cn" # cn | san_dns | san_uri | san_email
|
|
# allow = [] # exact identities; empty = any the CA issued
|
|
# allow_patterns = [] # RE2, anchor them yourself
|
|
|
|
## TCP chain sink (stdlib client; forwards to downstream tcp_chain source)
|
|
## Do NOT point a chain sink at a chain source in the SAME pipeline: entries
|
|
## loop back in and amplify without bound.
|
|
# [[pipelines.plugin_sinks]]
|
|
# id = "chain_out"
|
|
# type = "tcp_chain"
|
|
# [pipelines.plugin_sinks.config]
|
|
# host = "10.0.0.1" # Required
|
|
# port = 9440 # Required
|
|
# node = "" # origin label, default hostname; preserved across hops
|
|
# buffer_size = 1000
|
|
# dial_timeout_ms = 5000
|
|
# write_timeout_ms = 5000
|
|
# backoff_min_ms = 500
|
|
# backoff_max_ms = 30000
|
|
# keep_alive = true
|
|
# keep_alive_period_ms = 30000
|
|
# [pipelines.plugin_sinks.config.tls]
|
|
# enabled = true # example: mTLS dialer
|
|
# ca_file = "/etc/logwisp/tls/ca.crt"
|
|
# server_name = ""
|
|
# insecure_skip_verify = false
|
|
# cert_file = "/etc/logwisp/tls/client.crt"
|
|
# key_file = "/etc/logwisp/tls/client.key"
|
|
# min_version = "1.3"
|
|
# [pipelines.plugin_sinks.config.auth] # pin the downstream server's identity
|
|
# type = "none" # none | mtls; mtls requires tls.enabled
|
|
# identity = "cn" # cn | san_dns | san_uri | san_email
|
|
# allow = [] # exact identities; empty = any the CA issued
|
|
# allow_patterns = [] # RE2, anchor them yourself
|
|
|
|
## HTTP chain sink (stdlib client; batched NDJSON POST to downstream http_chain source)
|
|
# [[pipelines.plugin_sinks]]
|
|
# id = "hchain_out"
|
|
# type = "http_chain"
|
|
# [pipelines.plugin_sinks.config]
|
|
# host = "10.0.0.1" # Required
|
|
# port = 9441 # Required
|
|
# ingest_path = "/ingest"
|
|
# node = "" # origin label, default hostname; preserved across hops
|
|
# buffer_size = 1000
|
|
# max_batch_count = 100
|
|
# max_batch_bytes = 1048576
|
|
# flush_interval_ms = 1000
|
|
# request_timeout_ms = 10000 # Covers dial + write + response
|
|
# backoff_min_ms = 500
|
|
# backoff_max_ms = 30000
|
|
# [pipelines.plugin_sinks.config.tls]
|
|
# enabled = true # example: mTLS dialer
|
|
# ca_file = "/etc/logwisp/tls/ca.crt"
|
|
# cert_file = "/etc/logwisp/tls/client.crt"
|
|
# key_file = "/etc/logwisp/tls/client.key"
|
|
# [pipelines.plugin_sinks.config.auth] # pin the downstream server's identity
|
|
# type = "none" # none | mtls; mtls requires tls.enabled
|
|
# identity = "cn" # cn | san_dns | san_uri | san_email
|
|
# allow = [] # exact identities; empty = any the CA issued
|
|
# allow_patterns = [] # RE2, anchor them yourself
|