Logs Action
The Logs action fetches and queries logs from various backends. Use it to retrieve logs for debugging, analysis, or to pass to downstream actions like AI analysis.
kubernetes-logs.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: kubernetes-logs
namespace: mc
spec:
title: Kubernetes Logs
icon: logs
category: Logs
description: Fetch logs from Kubernetes
configs:
- types:
- Kubernetes::Pod
- Kubernetes::Deployment
- Kubernetes::StatefulSet
- Kubernetes::DaemonSet
parameters:
- name: limit
label: Limit
description: The maximum number of logs to fetch
required: false
default: "100"
actions:
- name: Fetch logs from Loki
logs:
kubernetes:
kind: $(.config.config_class)
apiVersion: $(.config.config.apiVersion)
namespace: $(.config.tags.namespace)
name: $(.config.name)
limit: $(.params.limit)
start: now-2h
| Field | Description | Scheme |
|---|---|---|
name* | Step Name |
|
logs | Logs Action | |
delay | A delay before running the action e.g. |
|
filter | Conditionally run an action | CEL with Playbook Context |
runsOn | Which runner (agent) to run the action on | |
templatesOn | Where templating (and secret management) of actions should occur |
|
timeout | Timeout on this action. |
Logs
Specify exactly one backend. All of the post processing fields are set inside the backend, alongside its query.
| Field | Description | Scheme |
|---|---|---|
cloudwatch | Query logs from AWS CloudWatch Logs | |
kubernetes | Fetch logs directly from Kubernetes pods | |
loki | Query logs from Grafana Loki | |
opensearch | Query logs from OpenSearch/Elasticsearch |
Post processing
Every backend accepts the following fields to filter, parse and deduplicate logs after they have been retrieved.
| Field | Description | Scheme |
|---|---|---|
dedupe.fields | Fields to use for identifying duplicate log entries (e.g., |
|
dedupe.window | Time window for deduplication (e.g., | |
mapping.dedupBy | Fields to dedupe the returned logs by |
|
mapping.groupBy | Fields to group the returned logs by |
|
mapping.host | Source field names for the host |
|
mapping.id | Source field names for the unique log identifier |
|
mapping.ignore | Fields to drop from the log labels |
|
mapping.message | Source field names for the log message content |
|
mapping.severity | Source field names for the log level/severity |
|
mapping.source | Source field names for the log source |
|
mapping.timestamp | Source field names for the timestamp (tries each until non-empty) |
|
match | CEL expressions to filter logs after retrieval. A log is kept if any of the expressions match | |
parse | Log format to parse the message with |
|
Time range
The cloudwatch, kubernetes and loki backends share a common time range and limit.
| Field | Description | Scheme |
|---|---|---|
end | End time of the query. Defaults to now |
|
limit | Maximum number of log lines to return |
|
start | Start time of the query. Supports datemath e.g. |
|
CloudWatch
Query logs from AWS CloudWatch Logs using CloudWatch Logs Insights.
| Field | Description | Scheme |
|---|---|---|
logGroup* | CloudWatch log group to query |
|
query* | CloudWatch Logs Insights query to run on the log group |
|
accessKey | AWS access key ID | |
assumeRole | ARN of the role to assume |
|
connection | AWS connection for credentials | |
endpoint | Custom AWS endpoint |
|
region | AWS region (e.g., |
|
secretKey | AWS secret access key | |
sessionToken | AWS session token | |
skipTLSVerify | Skip TLS verification when connecting to AWS |
|
Example
cloudwatch.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: cloudwatch-events
namespace: mc
spec:
title: Cloudwatch Events
icon: cloudwatch
category: Logs
description: Fetch events from Cloudwatch
parameters:
- name: logGroup
label: Log Group
description: The log group to fetch events from
required: true
- name: limit
label: Limit
description: The maximum number of events to fetch
required: false
default: '100'
configs:
- types:
- AWS::::Account
actions:
- name: Fetch events from CloudWatch
logs:
cloudwatch:
start: now-24h
limit: $(.params.limit)
logGroup: $(.params.logGroup)
query: |
fields @message, @timestamp, @logStream, @log
| sort @timestamp desc
| limit $(.params.limit)
Kubernetes
Fetch logs directly from Kubernetes pods using the Kubernetes API. Logs are fetched for the resource identified by kind, apiVersion, namespace and name — for a workload such as a Deployment, logs from all of its pods are returned.
| Field | Description | Scheme |
|---|---|---|
apiVersion | API version of the resource |
|
connection | Kubernetes connection for cluster access | |
containers | Fetch logs from only these containers | |
kind | Kind of the resource to fetch logs for e.g. |
|
kubeconfig | Kubeconfig content or path | |
name | Name of the resource |
|
namespace | Namespace of the resource |
|
pods | Include pods matching any of these selectors. Applies when fetching logs at a higher resource level, such as a deployment spanning multiple pods |
Example
k8s.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: kubernetes-logs
namespace: mc
spec:
title: Kubernetes Logs
icon: logs
category: Logs
description: Fetch logs from Kubernetes
configs:
- types:
- Kubernetes::Pod
- Kubernetes::Deployment
- Kubernetes::StatefulSet
- Kubernetes::DaemonSet
parameters:
- name: limit
label: Limit
description: The maximum number of logs to fetch
required: false
default: "100"
actions:
- name: Fetch logs from Loki
logs:
kubernetes:
kind: $(.config.config_class)
apiVersion: $(.config.config.apiVersion)
namespace: $(.config.tags.namespace)
name: $(.config.name)
limit: $(.params.limit)
start: now-2h
Loki
Query logs from Grafana Loki using LogQL.
| Field | Description | Scheme |
|---|---|---|
query* | LogQL query (e.g., |
|
connection | Connection name for Loki credentials | |
direction | Query direction: |
|
interval | Only return entries at or greater than this interval |
|
password | Basic auth password | |
since | Duration used to calculate |
|
step | Query resolution step width, as a duration or a number of seconds |
|
url | Loki server URL (e.g., |
|
username | Basic auth username |
Example
loki.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: loki-logs
namespace: mc
spec:
title: Loki Logs
icon: logs
category: Logs
description: Fetch logs from Loki
configs:
- types:
- Kubernetes::Pod
- Kubernetes::Deployment
parameters:
- name: limit
label: Limit
description: The maximum number of logs to fetch
required: false
default: "100"
actions:
- name: Fetch logs from Loki
logs:
loki:
url: https://logs-prod-111.grafana.net
username:
valueFrom:
secretKeyRef:
name: loki-grafana-cloud
key: userid
password:
valueFrom:
secretKeyRef:
name: loki-grafana-cloud
key: password
query: |
{namespace="{{ .config.tags.namespace }}",{{.config.config_class | toLower}}="{{ .config.name }}"}
limit: $(.params.limit)
start: now-2h
match:
- severity != "info" && severity != "unknown"
- labels.service == 'payment'
dedupe:
window: 1h
fields:
- message
OpenSearch
Query logs from OpenSearch or Elasticsearch clusters.
| Field | Description | Scheme |
|---|---|---|
index* | Index name or pattern (e.g., |
|
query* | OpenSearch query DSL |
|
address | OpenSearch cluster address |
|
connection | Connection name for OpenSearch credentials | |
limit | Maximum number of documents to return |
|
password | Basic auth password | |
username | Basic auth username |
Example
opensearch.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: opensearch-logs
namespace: mc
spec:
title: OpenSearch Logs
icon: elasticsearch
category: Logs
description: Fetch logs from OpenSearch
configs:
- types:
- Kubernetes::Pod
- Kubernetes::Deployment
parameters:
- name: limit
label: Limit
description: The maximum number of logs to fetch
required: false
default: '100'
actions:
- name: Fetch logs from OpenSearch
logs:
opensearch:
address: http://localhost:9200
query: |
{
"query": {
"bool": {
"filter": [
{ "term": { "kubernetes.namespace": "$(.config.tags.namespace)" } },
{ "term": { "kubernetes.labels.app": "$(.config.name)" } }
]
}
}
}
index: k8s-logs
limit: $(.params.limit)
Output
The action returns a structured result containing the retrieved logs.
| Field | Description | Scheme |
|---|---|---|
groups | Logs grouped by | []LogGroup |
logs | Log entries with normalized fields | |
metadata | Backend specific metadata about the query | map[string]any |
Log line
| Field | Description | Scheme |
|---|---|---|
count | Number of occurrences the line was deduped from |
|
firstObserved | Time the log line was first seen | time |
hash | Hash of the tokenized message, used to group similar lines |
|
host | Host the log originated from |
|
id | Unique identifier of the log line |
|
labels | Remaining fields from the log line |
|
lastObserved | Time the log line was last seen. Set when the line has been deduped | time |
message | Log message |
|
severity | Log level |
|
source | Source of the log |
|
Using Results in Subsequent Actions
actions:
- name: fetch-logs
logs:
kubernetes:
kind: Deployment
apiVersion: apps/v1
namespace: production
name: api
start: now-1h
- name: analyze
if: 'size(getAction("fetch-logs").result.logs) > 0'
ai:
prompt: |
Analyze these log entries:
{{.actions.fetch-logs.result.logs | toJSON}}
Templating
CEL Expressions
The following variables can be used within the CEL expressions of filter, if, delays and parameters.default:
| Field | Description | Schema |
|---|---|---|
config | Config passed to the playbook | ConfigItem |
check | Canary Check passed to the playbook | Check |
playbook | Playbook passed to the playbook | Playbook |
run | Current run | Run |
params | User provided parameters to the playbook | map[string]any |
request | Webhook request | Webhook Request |
env | Environment variables defined on the playbook | map[string]any |
user.name | Name of the user who invoked the action | string |
user.email | Email of the user who invoked the action | string |
agent.id | ID of the agent the resource belongs to. | string |
agent.name | Name of the agent the resource belongs to. | string |
Conditionally Running Actions
Playbook actions can be selectively executed based on CEL expressions. These expressions must either return
- a boolean value (
trueindicating run the action & skip the action otherwise) - or a special function among the ones listed below
| Function | Description |
|---|---|
always() | run no matter what; even if the playbook is cancelled/fails |
failure() | run if any of the previous actions failed |
skip() | skip running this action |
success() | run only if all previous actions succeeded (default) |
timeout() | run only if any of the previous actions timed out |
delete-kubernetes-pod.yaml---
apiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: notify-send-with-filter
spec:
parameters:
- name: message
label: The message for notification
default: '{{.config.name}}'
configs:
- types:
- Kubernetes::Pod
actions:
- name: Send notification
exec:
script: notify-send "{{.config.name}} was created"
- name: Bad script
exec:
script: deltaforce
- name: Send all success notification
if: success() # this filter practically skips this action as the second action above always fails
exec:
script: notify-send "Everything went successfully"
- name: Send notification regardless
if: always()
exec:
script: notify-send "a Pod config was created"
Defaulting Parameters
delete-kubernetes-pod.yamlapiVersion:
mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: edit
spec:
title: 'Edit Kustomize Resource'
icon: flux
parameters:
- default: 'chore: update $(.config.type)/$(.config.name)'
name: commit_message
Go Templating
When templating actions with Go Templates, the context variables are available as fields of the template's context object . eg .config, .user.email
Templating Actions
delete-kubernetes-pod.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: scale-deployment
spec:
description: Scale Deployment
configs:
- types:
- Kubernetes::Deployment
parameters:
- name: replicas
label: The new desired number of replicas.
actions:
- name: kubectl scale
exec:
script: |
kubectl scale --replicas={{.params.replicas}} \
--namespace={{.config.tags.namespace}} \
deployment {{.config.name}}
Functions
| Function | Description | Return |
|---|---|---|
getLastAction() | Returns the result of the action that just run | Action Specific |
getAction({action}) | Return the result of a specific action | Action Specific |
Reusing Action Results
action-results.yamlapiVersion: mission-control.flanksource.com/v1
kind: Playbook
metadata:
name: use-previous-action-result
spec:
description: Creates a file with the content of the config
configs:
- types:
- Kubernetes::Pod
actions:
- name: Fetch all changes
sql:
query: SELECT id FROM config_changes WHERE config_id = '{{.config.id}}'
driver: postgres
connection: connection://postgres/local
- name: Send notification
if: 'last_result().count > 0'
notification:
title: 'Changes summary for {{.config.name}}'
connection: connection://slack/flanksource
message: |
{{$rows:=index last_result "count"}}
Found {{$rows}} changes