Logs
The Logs scraper queries log aggregation systems to extract configuration changes from log entries. It supports multiple log backends including Loki, GCP Cloud Logging, OpenSearch, and BigQuery. This allows you to create configuration items and track changes based on log data.
Use Cases
- Application Configuration Changes: Track config reloads and updates from application logs
- Deployment Tracking: Monitor deployment events from CI/CD pipeline logs
- Error Analysis: Create configuration items from error patterns in logs
- Audit Trail: Track security and compliance events from audit logs
- Performance Monitoring: Extract performance metrics as configuration changes
logs-scraper.yamlapiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: app-config-changes
namespace: mc
spec:
full: true
logs:
- id: None
type: None
loki:
url: http://localhost:3100
query: '{job="app"} |~ "Configuration reloaded:.*changed from.*to"'
limit: '50'
start: 24h
transform:
expr: |
dyn(config.logs).map(line, {
"changes": [
{
"external_change_id": line.hash,
"change_type": "ConfigReload",
"external_id": "fdee1b15-4579-499e-adc5-2817735ec3f6",
"config_type": "Azure::AppRegistration",
"created_at": line.firstObserved,
"scraper_id": "all"
}
]
}).toJSON()
# curl -X POST http://localhost:3100/loki/api/v1/push \
# -H "Content-Type: application/json" \
# -d '{
# "streams": [
# {
# "stream": {
# "job": "app"
# },
# "values": [
# ["'$(date +%s%N)'", "Configuration reloaded: database.max_connections changed from 100 to 200"],
# ["'$(date +%s%N)'", "Configuration reloaded: server.timeout changed from 30s to 60s"],
# ["'$(date +%s%N)'", "Configuration reloaded: cache.size changed from 1GB to 2GB"]
# ]
# }
# ]
# }'
Field | Description | Scheme | Required |
---|---|---|---|
schedule | Specify the interval to scrape in cron format. Defaults to every 60 minutes. | Cron | |
retention | Settings for retaining changes, analysis and scraped items | Retention | |
logs | Specifies the list of log configurations to scrape. | []Logs | true |
Logs
Mapping
Custom scrapers require you to define the id
and type
for each scraped item. For example, when you scrape a file containing a JSON array, where each array element represents a config item, you must specify the id
and type
for those items.
You can achieve this by using mappings in your custom scraper configuration.
Field | Description | Scheme |
---|---|---|
id* | A static value or JSONPath expression to use as the ID for the resource. |
|
name* | A static value or JSONPath expression to use as the name for the resource. |
|
type* | A static value or JSONPath expression to use as the type for the resource. |
|
class | A static value or JSONPath expression to use as the class for the resource. |
|
createFields | A list of JSONPath expressions used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
deleteFields | A list of JSONPath expressions used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
description | A static value or JSONPath expression to use as the description for the resource. |
|
format | Format of config item, defaults to JSON, available options are JSON, properties. See Formats |
|
health | A static value or JSONPath expression to use as the health of the config item. |
|
items | A JSONPath expression to use to extract individual items from the resource. Items are extracted first and then the ID, Name, Type and transformations are applied for each item. | |
status | A static value or JSONPath expression to use as the status of the config item. |
|
timestampFormat | A Go time format string used to parse timestamps in createFields and deleteFields. (Default: RFC3339) |
|
Formats
JSON
The scraper stores config items as jsonb
fields in PostgreSQL.
Resource providers typically return the JSON used. e.g. kubectl get -o json
or aws --output=json
.
When you display the config, the UI automatically converts the JSON data to YAML for improved readability.
XML / Properties
The scraper stores non-JSON files as JSON using:
{ 'format': 'xml', 'content': '<root>..</root>' }
You can still access non-JSON content in scripts using config.content
.
The UI formats and renders XML appropriately.
Extracting Changes & Access Logs
Custom scrapers ingest changes & access logs from external systems when you enable the full
option.
Every single config is expected to have at these 3 top-level fields
config
changes
access_logs
They could have more fields or even missing some of these fields. The point is that only these fields are extracted.
Consider a file that contains the following json data.
{
"reg_no": "A123",
"config": {
"meta": "this is the actual config that'll be stored."
},
"changes": [
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
],
"access_logs": [
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
}
A regular scraper saves the entire json as a config.
However, with the full
option, the scraper extracts the config, changes and access logs.
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: file-scraper
spec:
full: true
file:
- type: Car
id: $.reg_no
paths:
- fixtures/data/car_changes.json
The resulting config is:
{
"meta": "this is the actual config that'll be stored."
}
and the scraper records the following new config change on that config:
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
and the access logs will be saved to
[
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
LokiConfig
Mapping
Custom scrapers require you to define the id
and type
for each scraped item. For example, when you scrape a file containing a JSON array, where each array element represents a config item, you must specify the id
and type
for those items.
You can achieve this by using mappings in your custom scraper configuration.
Field | Description | Scheme |
---|---|---|
id* | A static value or JSONPath expression to use as the ID for the resource. |
|
name* | A static value or JSONPath expression to use as the name for the resource. |
|
type* | A static value or JSONPath expression to use as the type for the resource. |
|
class | A static value or JSONPath expression to use as the class for the resource. |
|
createFields | A list of JSONPath expressions used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
deleteFields | A list of JSONPath expressions used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
description | A static value or JSONPath expression to use as the description for the resource. |
|
format | Format of config item, defaults to JSON, available options are JSON, properties. See Formats |
|
health | A static value or JSONPath expression to use as the health of the config item. |
|
items | A JSONPath expression to use to extract individual items from the resource. Items are extracted first and then the ID, Name, Type and transformations are applied for each item. | |
status | A static value or JSONPath expression to use as the status of the config item. |
|
timestampFormat | A Go time format string used to parse timestamps in createFields and deleteFields. (Default: RFC3339) |
|
Formats
JSON
The scraper stores config items as jsonb
fields in PostgreSQL.
Resource providers typically return the JSON used. e.g. kubectl get -o json
or aws --output=json
.
When you display the config, the UI automatically converts the JSON data to YAML for improved readability.
XML / Properties
The scraper stores non-JSON files as JSON using:
{ 'format': 'xml', 'content': '<root>..</root>' }
You can still access non-JSON content in scripts using config.content
.
The UI formats and renders XML appropriately.
Extracting Changes & Access Logs
Custom scrapers ingest changes & access logs from external systems when you enable the full
option.
Every single config is expected to have at these 3 top-level fields
config
changes
access_logs
They could have more fields or even missing some of these fields. The point is that only these fields are extracted.
Consider a file that contains the following json data.
{
"reg_no": "A123",
"config": {
"meta": "this is the actual config that'll be stored."
},
"changes": [
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
],
"access_logs": [
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
}
A regular scraper saves the entire json as a config.
However, with the full
option, the scraper extracts the config, changes and access logs.
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: file-scraper
spec:
full: true
file:
- type: Car
id: $.reg_no
paths:
- fixtures/data/car_changes.json
The resulting config is:
{
"meta": "this is the actual config that'll be stored."
}
and the scraper records the following new config change on that config:
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
and the access logs will be saved to
[
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
GCPCloudLoggingConfig
Mapping
Custom scrapers require you to define the id
and type
for each scraped item. For example, when you scrape a file containing a JSON array, where each array element represents a config item, you must specify the id
and type
for those items.
You can achieve this by using mappings in your custom scraper configuration.
Field | Description | Scheme |
---|---|---|
id* | A static value or JSONPath expression to use as the ID for the resource. |
|
name* | A static value or JSONPath expression to use as the name for the resource. |
|
type* | A static value or JSONPath expression to use as the type for the resource. |
|
class | A static value or JSONPath expression to use as the class for the resource. |
|
createFields | A list of JSONPath expressions used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
deleteFields | A list of JSONPath expressions used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
description | A static value or JSONPath expression to use as the description for the resource. |
|
format | Format of config item, defaults to JSON, available options are JSON, properties. See Formats |
|
health | A static value or JSONPath expression to use as the health of the config item. |
|
items | A JSONPath expression to use to extract individual items from the resource. Items are extracted first and then the ID, Name, Type and transformations are applied for each item. | |
status | A static value or JSONPath expression to use as the status of the config item. |
|
timestampFormat | A Go time format string used to parse timestamps in createFields and deleteFields. (Default: RFC3339) |
|
Formats
JSON
The scraper stores config items as jsonb
fields in PostgreSQL.
Resource providers typically return the JSON used. e.g. kubectl get -o json
or aws --output=json
.
When you display the config, the UI automatically converts the JSON data to YAML for improved readability.
XML / Properties
The scraper stores non-JSON files as JSON using:
{ 'format': 'xml', 'content': '<root>..</root>' }
You can still access non-JSON content in scripts using config.content
.
The UI formats and renders XML appropriately.
Extracting Changes & Access Logs
Custom scrapers ingest changes & access logs from external systems when you enable the full
option.
Every single config is expected to have at these 3 top-level fields
config
changes
access_logs
They could have more fields or even missing some of these fields. The point is that only these fields are extracted.
Consider a file that contains the following json data.
{
"reg_no": "A123",
"config": {
"meta": "this is the actual config that'll be stored."
},
"changes": [
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
],
"access_logs": [
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
}
A regular scraper saves the entire json as a config.
However, with the full
option, the scraper extracts the config, changes and access logs.
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: file-scraper
spec:
full: true
file:
- type: Car
id: $.reg_no
paths:
- fixtures/data/car_changes.json
The resulting config is:
{
"meta": "this is the actual config that'll be stored."
}
and the scraper records the following new config change on that config:
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
and the access logs will be saved to
[
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
OpenSearchConfig
Mapping
Custom scrapers require you to define the id
and type
for each scraped item. For example, when you scrape a file containing a JSON array, where each array element represents a config item, you must specify the id
and type
for those items.
You can achieve this by using mappings in your custom scraper configuration.
Field | Description | Scheme |
---|---|---|
id* | A static value or JSONPath expression to use as the ID for the resource. |
|
name* | A static value or JSONPath expression to use as the name for the resource. |
|
type* | A static value or JSONPath expression to use as the type for the resource. |
|
class | A static value or JSONPath expression to use as the class for the resource. |
|
createFields | A list of JSONPath expressions used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
deleteFields | A list of JSONPath expressions used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
description | A static value or JSONPath expression to use as the description for the resource. |
|
format | Format of config item, defaults to JSON, available options are JSON, properties. See Formats |
|
health | A static value or JSONPath expression to use as the health of the config item. |
|
items | A JSONPath expression to use to extract individual items from the resource. Items are extracted first and then the ID, Name, Type and transformations are applied for each item. | |
status | A static value or JSONPath expression to use as the status of the config item. |
|
timestampFormat | A Go time format string used to parse timestamps in createFields and deleteFields. (Default: RFC3339) |
|
Formats
JSON
The scraper stores config items as jsonb
fields in PostgreSQL.
Resource providers typically return the JSON used. e.g. kubectl get -o json
or aws --output=json
.
When you display the config, the UI automatically converts the JSON data to YAML for improved readability.
XML / Properties
The scraper stores non-JSON files as JSON using:
{ 'format': 'xml', 'content': '<root>..</root>' }
You can still access non-JSON content in scripts using config.content
.
The UI formats and renders XML appropriately.
Extracting Changes & Access Logs
Custom scrapers ingest changes & access logs from external systems when you enable the full
option.
Every single config is expected to have at these 3 top-level fields
config
changes
access_logs
They could have more fields or even missing some of these fields. The point is that only these fields are extracted.
Consider a file that contains the following json data.
{
"reg_no": "A123",
"config": {
"meta": "this is the actual config that'll be stored."
},
"changes": [
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
],
"access_logs": [
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
}
A regular scraper saves the entire json as a config.
However, with the full
option, the scraper extracts the config, changes and access logs.
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: file-scraper
spec:
full: true
file:
- type: Car
id: $.reg_no
paths:
- fixtures/data/car_changes.json
The resulting config is:
{
"meta": "this is the actual config that'll be stored."
}
and the scraper records the following new config change on that config:
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
and the access logs will be saved to
[
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
BigQueryConfig
Mapping
Custom scrapers require you to define the id
and type
for each scraped item. For example, when you scrape a file containing a JSON array, where each array element represents a config item, you must specify the id
and type
for those items.
You can achieve this by using mappings in your custom scraper configuration.
Field | Description | Scheme |
---|---|---|
id* | A static value or JSONPath expression to use as the ID for the resource. |
|
name* | A static value or JSONPath expression to use as the name for the resource. |
|
type* | A static value or JSONPath expression to use as the type for the resource. |
|
class | A static value or JSONPath expression to use as the class for the resource. |
|
createFields | A list of JSONPath expressions used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
deleteFields | A list of JSONPath expressions used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
description | A static value or JSONPath expression to use as the description for the resource. |
|
format | Format of config item, defaults to JSON, available options are JSON, properties. See Formats |
|
health | A static value or JSONPath expression to use as the health of the config item. |
|
items | A JSONPath expression to use to extract individual items from the resource. Items are extracted first and then the ID, Name, Type and transformations are applied for each item. | |
status | A static value or JSONPath expression to use as the status of the config item. |
|
timestampFormat | A Go time format string used to parse timestamps in createFields and deleteFields. (Default: RFC3339) |
|
Formats
JSON
The scraper stores config items as jsonb
fields in PostgreSQL.
Resource providers typically return the JSON used. e.g. kubectl get -o json
or aws --output=json
.
When you display the config, the UI automatically converts the JSON data to YAML for improved readability.
XML / Properties
The scraper stores non-JSON files as JSON using:
{ 'format': 'xml', 'content': '<root>..</root>' }
You can still access non-JSON content in scripts using config.content
.
The UI formats and renders XML appropriately.
Extracting Changes & Access Logs
Custom scrapers ingest changes & access logs from external systems when you enable the full
option.
Every single config is expected to have at these 3 top-level fields
config
changes
access_logs
They could have more fields or even missing some of these fields. The point is that only these fields are extracted.
Consider a file that contains the following json data.
{
"reg_no": "A123",
"config": {
"meta": "this is the actual config that'll be stored."
},
"changes": [
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
],
"access_logs": [
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
}
A regular scraper saves the entire json as a config.
However, with the full
option, the scraper extracts the config, changes and access logs.
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: file-scraper
spec:
full: true
file:
- type: Car
id: $.reg_no
paths:
- fixtures/data/car_changes.json
The resulting config is:
{
"meta": "this is the actual config that'll be stored."
}
and the scraper records the following new config change on that config:
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
and the access logs will be saved to
[
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
FieldMappingConfig
Mapping
Custom scrapers require you to define the id
and type
for each scraped item. For example, when you scrape a file containing a JSON array, where each array element represents a config item, you must specify the id
and type
for those items.
You can achieve this by using mappings in your custom scraper configuration.
Field | Description | Scheme |
---|---|---|
id* | A static value or JSONPath expression to use as the ID for the resource. |
|
name* | A static value or JSONPath expression to use as the name for the resource. |
|
type* | A static value or JSONPath expression to use as the type for the resource. |
|
class | A static value or JSONPath expression to use as the class for the resource. |
|
createFields | A list of JSONPath expressions used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
deleteFields | A list of JSONPath expressions used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used. | []jsonpath |
description | A static value or JSONPath expression to use as the description for the resource. |
|
format | Format of config item, defaults to JSON, available options are JSON, properties. See Formats |
|
health | A static value or JSONPath expression to use as the health of the config item. |
|
items | A JSONPath expression to use to extract individual items from the resource. Items are extracted first and then the ID, Name, Type and transformations are applied for each item. | |
status | A static value or JSONPath expression to use as the status of the config item. |
|
timestampFormat | A Go time format string used to parse timestamps in createFields and deleteFields. (Default: RFC3339) |
|
Formats
JSON
The scraper stores config items as jsonb
fields in PostgreSQL.
Resource providers typically return the JSON used. e.g. kubectl get -o json
or aws --output=json
.
When you display the config, the UI automatically converts the JSON data to YAML for improved readability.
XML / Properties
The scraper stores non-JSON files as JSON using:
{ 'format': 'xml', 'content': '<root>..</root>' }
You can still access non-JSON content in scripts using config.content
.
The UI formats and renders XML appropriately.
Extracting Changes & Access Logs
Custom scrapers ingest changes & access logs from external systems when you enable the full
option.
Every single config is expected to have at these 3 top-level fields
config
changes
access_logs
They could have more fields or even missing some of these fields. The point is that only these fields are extracted.
Consider a file that contains the following json data.
{
"reg_no": "A123",
"config": {
"meta": "this is the actual config that'll be stored."
},
"changes": [
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
],
"access_logs": [
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
}
A regular scraper saves the entire json as a config.
However, with the full
option, the scraper extracts the config, changes and access logs.
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: file-scraper
spec:
full: true
file:
- type: Car
id: $.reg_no
paths:
- fixtures/data/car_changes.json
The resulting config is:
{
"meta": "this is the actual config that'll be stored."
}
and the scraper records the following new config change on that config:
{
"action": "drive",
"summary": "car color changed to blue",
"unrelated_stuff": 123
}
and the access logs will be saved to
[
{
"config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0",
"external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6",
"created_at": "2025-01-01"
},
{
"config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f",
"external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632",
"created_at": "2025-01-02"
}
]
Configuration Examples
Loki Integration
loki-config-changes.yamlapiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: app-config-changes
namespace: mc
spec:
full: true
logs:
- id: None
type: None
loki:
url: http://localhost:3100
query: '{job="app"} |~ "Configuration reloaded:.*changed from.*to"'
limit: '50'
start: 24h
transform:
expr: |
dyn(config.logs).map(line, {
"changes": [
{
"external_change_id": line.hash,
"change_type": "ConfigReload",
"external_id": "fdee1b15-4579-499e-adc5-2817735ec3f6",
"config_type": "Azure::AppRegistration",
"created_at": line.firstObserved,
"scraper_id": "all"
}
]
}).toJSON()
# curl -X POST http://localhost:3100/loki/api/v1/push \
# -H "Content-Type: application/json" \
# -d '{
# "streams": [
# {
# "stream": {
# "job": "app"
# },
# "values": [
# ["'$(date +%s%N)'", "Configuration reloaded: database.max_connections changed from 100 to 200"],
# ["'$(date +%s%N)'", "Configuration reloaded: server.timeout changed from 30s to 60s"],
# ["'$(date +%s%N)'", "Configuration reloaded: cache.size changed from 1GB to 2GB"]
# ]
# }
# ]
# }'
BigQuery Log Analysis
bigquery-github-commits.yamlapiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: github-commits-logs
namespace: mc
spec:
full: true
schedule: '@every 1h'
logs:
- name: golang-github-commits
id: None
type: None
transform:
expr: |
dyn(config.logs).map(line, {
"changes": [
{
"external_change_id": line.id,
"change_type": "Commit",
"external_id": "github://golang/go",
"config_type": "GitHub::Repository",
"created_at": line.firstObserved,
"summary": line.message,
"scraper_id": "all"
}
]
}).toJSON()
bigQuery:
project: workload-prod-eu-02
query: |
SELECT
FORMAT_TIMESTAMP('%Y-%m-%dT%H:%M:%SZ', TIMESTAMP_SECONDS(committer.date.seconds)) as timestamp,
CASE
WHEN REGEXP_CONTAINS(LOWER(message), r'fix|bug|error') THEN 'high'
WHEN REGEXP_CONTAINS(LOWER(message), r'feat|add|new') THEN 'medium'
ELSE 'info'
END as severity,
message,
commit
FROM `bigquery-public-data.github_repos.commits`
Where 'golang/go' IN UNNEST(repo_name)
ORDER BY committer.date.seconds DESC
LIMIT 100
fieldMapping:
timestamp: ['timestamp']
severity: ['severity']
message: ['message']
id: ['commit']
GCP Cloud Logging
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: gcp-audit-logs
spec:
logs:
- gcpCloudLogging:
project: my-gcp-project
filter: |
protoPayload.serviceName="compute.googleapis.com"
protoPayload.methodName:"compute.instances"
orderBy: timestamp desc
pageSize: 100
transform:
expr: |
dyn(config.logs).map(line, {
"changes": [{
"change_type": "GCPResourceChange",
"external_id": line.resource.labels.instance_id,
"config_type": "GCP::Instance",
"created_at": line.timestamp,
"summary": line.protoPayload.methodName
}]
}).toJSON()
OpenSearch Log Mining
apiVersion: configs.flanksource.com/v1
kind: ScrapeConfig
metadata:
name: opensearch-security-events
spec:
logs:
- openSearch:
url: https://opensearch-cluster:9200
index: security-logs-*
query: |
{
"query": {
"bool": {
"must": [
{"term": {"event_type": "authentication"}},
{"range": {"@timestamp": {"gte": "now-1h"}}}
]
}
}
}
size: 1000
username:
valueFrom:
secretKeyRef:
name: opensearch-creds
key: username
password:
valueFrom:
secretKeyRef:
name: opensearch-creds
key: password
fieldMapping:
timestamp: ['@timestamp', 'timestamp']
message: ['message', 'event_description']
severity: ['severity', 'log_level']
id: ['event_id', 'transaction_id']
The Logs scraper provides powerful integration with various log aggregation systems, enabling you to transform log data into actionable configuration insights and change tracking.