[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F60PHSQZ66FRYAF9YQH46P":3,"skill-same:01M6F60PHSQZ66FRYAF9YQH46P":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":32,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":6,"ownerHtmlUrl":62,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":63,"install":64,"resources":77},"01M6F60PHSQZ66FRYAF9YQH46P","elk-stack",null,"Deploy and manage the ELK Stack (Elasticsearch, Logstash, Kibana) for log aggregation and analysis.","boisenoise\u002Fskills-collections","boisenoise","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F193180?v=4","01M6CDBDQK6BDN55ZMA6B6PKBM","01M6CDBDVSJ3JPTBYN26FZ7TZK",12,"MIT","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-elk-stack\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"elk stack","stack","only","2026","relevant","logstash","scripts","critical","platform","main","community","log","security","access","kibana","analysis","devops-security","elasticsearch","kubectl","ci","git","2026-11-10 10:12:30",false,"---\nname: elk-stack\ndescription: Deploy and manage the ELK Stack (Elasticsearch, Logstash, Kibana) for\n  log aggregation and analysis.\ncategory: devops\nrisk: critical\nsource: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\nsource_repo: BagelHole\u002FDevOps-Security-Agent-Skills\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Requires the relevant platform CLIs (kubectl, helm, terraform, git,\n  CI runners) and authorized access to the target environment. Docs-only; helper scripts\n  and templates not bundled.\nmetadata:\n  author: devops-skills\n  version: '1.0'\n---\n\n# ELK Stack\n\nCentralize and analyze logs with Elasticsearch, Logstash, and Kibana.\n\n## When to Use This Skill\n\nUse this skill when:\n- Centralizing logs from multiple sources\n- Building log search and analytics platforms\n- Creating log-based dashboards and alerts\n- Implementing full-text search for logs\n- Processing and transforming log data\n\n## Prerequisites\n\n- Docker or server infrastructure\n- Sufficient disk space for log storage\n- Network access from log sources\n\n## Lab and production boundaries\n\nThe Compose file is a local disposable lab with Elasticsearch security disabled; loopback binding does not make it appropriate for shared networks. Production needs verified compatible patched versions, authentication\u002FTLS between components, least-privilege ingestion and reviewed retention. A read-only docker.sock mount still exposes daemon API capabilities; omit it or use a restricted proxy. Redact secrets\u002FPII before ingestion and restrict dashboards\u002Fexported logs. Watcher\u002Fwebhook creation sends recurring external messages and requires the corresponding user instruction. ILM snippets are version-dependent and need a correctly bootstrapped rollover alias\u002Fdata stream; date-named Logstash indices do not automatically satisfy that contract.\n\n## Docker Deployment\n\n```yaml\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n  elasticsearch:\n    image: docker.elastic.co\u002Felasticsearch\u002Felasticsearch:8.11.0\n    environment:\n      - discovery.type=single-node\n      - xpack.security.enabled=false\n      - \"ES_JAVA_OPTS=-Xms1g -Xmx1g\"\n    ports:\n      - \"127.0.0.1:9200:9200\"\n    volumes:\n      - elasticsearch-data:\u002Fusr\u002Fshare\u002Felasticsearch\u002Fdata\n\n  logstash:\n    image: docker.elastic.co\u002Flogstash\u002Flogstash:8.11.0\n    volumes:\n      - .\u002Flogstash\u002Fpipeline:\u002Fusr\u002Fshare\u002Flogstash\u002Fpipeline\n      - .\u002Flogstash\u002Fconfig:\u002Fusr\u002Fshare\u002Flogstash\u002Fconfig\n    ports:\n      - \"127.0.0.1:5044:5044\"\n      - \"127.0.0.1:5000:5000\"\n    depends_on:\n      - elasticsearch\n\n  kibana:\n    image: docker.elastic.co\u002Fkibana\u002Fkibana:8.11.0\n    ports:\n      - \"127.0.0.1:5601:5601\"\n    environment:\n      - ELASTICSEARCH_HOSTS=http:\u002F\u002Felasticsearch:9200\n    depends_on:\n      - elasticsearch\n\n  filebeat:\n    image: docker.elastic.co\u002Fbeats\u002Ffilebeat:8.11.0\n    user: root\n    volumes:\n      - .\u002Ffilebeat\u002Ffilebeat.yml:\u002Fusr\u002Fshare\u002Ffilebeat\u002Ffilebeat.yml:ro\n      - \u002Fvar\u002Flib\u002Fdocker\u002Fcontainers:\u002Fvar\u002Flib\u002Fdocker\u002Fcontainers:ro\n      - \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock:ro\n    depends_on:\n      - logstash\n\nvolumes:\n  elasticsearch-data:\n```\n\n## Elasticsearch Configuration\n\n### Index Templates\n\n```json\nPUT _index_template\u002Flogs-template\n{\n  \"index_patterns\": [\"logs-*\"],\n  \"template\": {\n    \"settings\": {\n      \"number_of_shards\": 1,\n      \"number_of_replicas\": 1,\n      \"index.lifecycle.name\": \"logs-policy\"\n    },\n    \"mappings\": {\n      \"properties\": {\n        \"@timestamp\": { \"type\": \"date\" },\n        \"message\": { \"type\": \"text\" },\n        \"level\": { \"type\": \"keyword\" },\n        \"service\": { \"type\": \"keyword\" },\n        \"host\": { \"type\": \"keyword\" },\n        \"trace_id\": { \"type\": \"keyword\" }\n      }\n    }\n  }\n}\n```\n\n### Index Lifecycle Management\n\n```json\nPUT _ilm\u002Fpolicy\u002Flogs-policy\n{\n  \"policy\": {\n    \"phases\": {\n      \"hot\": {\n        \"min_age\": \"0ms\",\n        \"actions\": {\n          \"rollover\": {\n            \"max_size\": \"50GB\",\n            \"max_age\": \"1d\"\n          }\n        }\n      },\n      \"warm\": {\n        \"min_age\": \"7d\",\n        \"actions\": {\n          \"shrink\": { \"number_of_shards\": 1 },\n          \"forcemerge\": { \"max_num_segments\": 1 }\n        }\n      },\n      \"cold\": {\n        \"min_age\": \"30d\",\n        \"actions\": {\n          \"freeze\": {}\n        }\n      },\n      \"delete\": {\n        \"min_age\": \"90d\",\n        \"actions\": {\n          \"delete\": {}\n        }\n      }\n    }\n  }\n}\n```\n\n## Logstash Pipeline\n\n### Basic Pipeline\n\n```ruby\n# logstash\u002Fpipeline\u002Fmain.conf\ninput {\n  beats {\n    port => 5044\n  }\n  \n  tcp {\n    port => 5000\n    codec => json_lines\n  }\n}\n\nfilter {\n  # Parse JSON logs\n  if [message] =~ \u002F^\\{\u002F {\n    json {\n      source => \"message\"\n    }\n  }\n  \n  # Parse timestamp\n  date {\n    match => [\"timestamp\", \"ISO8601\", \"yyyy-MM-dd HH:mm:ss\"]\n    target => \"@timestamp\"\n  }\n  \n  # Add environment tag\n  mutate {\n    add_field => { \"environment\" => \"production\" }\n  }\n  \n  # Grok pattern for nginx logs\n  if [type] == \"nginx\" {\n    grok {\n      match => {\n        \"message\" => '%{IPORHOST:client_ip} - %{USER:user} \\[%{HTTPDATE:timestamp}\\] \"%{WORD:method} %{URIPATHPARAM:request} HTTP\u002F%{NUMBER:http_version}\" %{NUMBER:status} %{NUMBER:bytes}'\n      }\n    }\n  }\n}\n\noutput {\n  elasticsearch {\n    hosts => [\"elasticsearch:9200\"]\n    index => \"logs-%{+YYYY.MM.dd}\"\n  }\n}\n```\n\n### Advanced Filtering\n\n```ruby\nfilter {\n  # Parse application logs\n  grok {\n    match => {\n      \"message\" => \"%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \\[%{DATA:service}\\] %{GREEDYDATA:log_message}\"\n    }\n  }\n  \n  # Extract trace ID from message\n  if [log_message] =~ \u002Ftrace_id=\u002F {\n    grok {\n      match => { \"log_message\" => \"trace_id=%{UUID:trace_id}\" }\n    }\n  }\n  \n  # GeoIP lookup\n  if [client_ip] {\n    geoip {\n      source => \"client_ip\"\n      target => \"geoip\"\n    }\n  }\n  \n  # Drop debug logs in production\n  if [level] == \"DEBUG\" and [environment] == \"production\" {\n    drop {}\n  }\n  \n  # Enrich with lookup\n  translate {\n    field => \"status\"\n    destination => \"status_description\"\n    dictionary => {\n      \"200\" => \"OK\"\n      \"404\" => \"Not Found\"\n      \"500\" => \"Internal Server Error\"\n    }\n  }\n}\n```\n\n## Filebeat Configuration\n\n```yaml\n# filebeat\u002Ffilebeat.yml\nfilebeat.inputs:\n  - type: container\n    paths:\n      - '\u002Fvar\u002Flib\u002Fdocker\u002Fcontainers\u002F*\u002F*.log'\n    processors:\n      - add_docker_metadata:\n          host: \"unix:\u002F\u002F\u002Fvar\u002Frun\u002Fdocker.sock\"\n\n  - type: log\n    enabled: true\n    paths:\n      - \u002Fvar\u002Flog\u002Fnginx\u002F*.log\n    tags: [\"nginx\"]\n    fields:\n      type: nginx\n\noutput.logstash:\n  hosts: [\"logstash:5044\"]\n\nlogging.level: info\nlogging.to_files: true\nlogging.files:\n  path: \u002Fvar\u002Flog\u002Ffilebeat\n  name: filebeat\n  keepfiles: 7\n```\n\n## Elasticsearch Queries\n\n### Basic Queries\n\n```json\n\u002F\u002F Search all logs\nGET logs-*\u002F_search\n{\n  \"query\": {\n    \"match_all\": {}\n  }\n}\n\n\u002F\u002F Search by keyword\nGET logs-*\u002F_search\n{\n  \"query\": {\n    \"match\": {\n      \"message\": \"error\"\n    }\n  }\n}\n\n\u002F\u002F Filter by field\nGET logs-*\u002F_search\n{\n  \"query\": {\n    \"bool\": {\n      \"must\": [\n        { \"match\": { \"level\": \"ERROR\" } },\n        { \"range\": { \"@timestamp\": { \"gte\": \"now-1h\" } } }\n      ],\n      \"filter\": [\n        { \"term\": { \"service\": \"api-gateway\" } }\n      ]\n    }\n  }\n}\n```\n\n### Aggregations\n\n```json\n\u002F\u002F Count by log level\nGET logs-*\u002F_search\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"log_levels\": {\n      \"terms\": { \"field\": \"level\" }\n    }\n  }\n}\n\n\u002F\u002F Error rate over time\nGET logs-*\u002F_search\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"errors_over_time\": {\n      \"date_histogram\": {\n        \"field\": \"@timestamp\",\n        \"fixed_interval\": \"5m\"\n      },\n      \"aggs\": {\n        \"error_count\": {\n          \"filter\": { \"term\": { \"level\": \"ERROR\" } }\n        }\n      }\n    }\n  }\n}\n```\n\n## Kibana Setup\n\n### Index Patterns\n\n1. Go to Stack Management → Index Patterns\n2. Create pattern: `logs-*`\n3. Set time field: `@timestamp`\n\n### Saved Searches\n\nCreate saved searches for common queries:\n- `level:ERROR` - All errors\n- `service:api-gateway AND level:ERROR` - API gateway errors\n- `response_time:>1000` - Slow requests\n\n### Visualizations\n\nCommon visualization types:\n- **Line Chart**: Error rate over time\n- **Pie Chart**: Distribution by log level\n- **Data Table**: Top error messages\n- **Metric**: Total error count\n\n### Dashboard Example\n\nCreate dashboard with:\n1. Total log count (Metric)\n2. Error rate trend (Line chart)\n3. Logs by service (Pie chart)\n4. Recent errors (Data table)\n5. Log stream (Discover panel)\n\n## Alerting\n\n### Watcher (X-Pack)\n\n```json\nPUT _watcher\u002Fwatch\u002Ferror_alert\n{\n  \"trigger\": {\n    \"schedule\": { \"interval\": \"5m\" }\n  },\n  \"input\": {\n    \"search\": {\n      \"request\": {\n        \"indices\": [\"logs-*\"],\n        \"body\": {\n          \"query\": {\n            \"bool\": {\n              \"must\": [\n                { \"match\": { \"level\": \"ERROR\" } },\n                { \"range\": { \"@timestamp\": { \"gte\": \"now-5m\" } } }\n              ]\n            }\n          }\n        }\n      }\n    }\n  },\n  \"condition\": {\n    \"compare\": { \"ctx.payload.hits.total.value\": { \"gt\": 100 } }\n  },\n  \"actions\": {\n    \"notify_slack\": {\n      \"webhook\": {\n        \"scheme\": \"https\",\n        \"host\": \"hooks.slack.com\",\n        \"port\": 443,\n        \"method\": \"post\",\n        \"path\": \"\u002Fservices\u002Fxxx\",\n        \"body\": \"{\\\"text\\\": \\\"High error rate detected: {{ctx.payload.hits.total.value}} errors in last 5 minutes\\\"}\"\n      }\n    }\n  }\n}\n```\n\n## Common Issues\n\n### Issue: High Disk Usage\n**Problem**: Elasticsearch consuming too much disk\n**Solution**: Implement ILM policies, reduce retention\n\n### Issue: Slow Searches\n**Problem**: Queries taking too long\n**Solution**: Optimize index settings, add more shards, use filters\n\n### Issue: Log Parsing Failures\n**Problem**: Logs not parsed correctly\n**Solution**: Test grok patterns, check for log format changes\n\n### Issue: Memory Pressure\n**Problem**: Elasticsearch OOM errors\n**Solution**: Increase heap size (max 50% of RAM), limit field data\n\n## Best Practices\n\n- Implement index lifecycle management\n- Use index templates for consistent mappings\n- Parse logs at ingestion time\n- Limit stored fields to reduce storage\n- Use data streams for time-series data\n- Monitor cluster health\n- Implement proper security (X-Pack)\n- Regular index maintenance\n\n## Related Skills\n\n- loki-logging (`loki-logging`) - Alternative logging stack\n- prometheus-grafana (`prometheus-grafana`) - Metrics monitoring\n- audit-logging (`audit-logging`) - Compliance logging\n\n## Limitations\n\n- Guidance executes against real environments: confirm target, blast radius, and rollback plan before applying anything.\n- Never deploy to production without explicit approval. Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\ngit status && git diff --stat\nkubectl diff -f manifest.yaml\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n","# ELK Stack\n\nCentralize and analyze logs with Elasticsearch, Logstash, and Kibana.\n\n## When to Use This Skill\n\nUse this skill when:\n- Centralizing logs from multiple sources\n- Building log search and analytics platforms\n- Creating log-based dashboards and alerts\n- Implementing full-text search for logs\n- Processing and transforming log data\n\n## Prerequisites\n\n- Docker or server infrastructure\n- Sufficient disk space for log storage\n- Network access from log sources\n\n## Lab and production boundaries\n\nThe Compose file is a local disposable lab with Elasticsearch security disabled; loopback binding does not make it appropriate for shared networks. Production needs verified compatible patched versions, authentication\u002FTLS between components, least-privilege ingestion and reviewed retention. A read-only docker.sock mount still exposes daemon API capabilities; omit it or use a restricted proxy. Redact secrets\u002FPII before ingestion and restrict dashboards\u002Fexported logs. Watcher\u002Fwebhook creation sends recurring external messages and requires the corresponding user instruction. ILM snippets are version-dependent and need a correctly bootstrapped rollover alias\u002Fdata stream; date-named Logstash indices do not automatically satisfy that contract.\n\n## Docker Deployment\n\n```yaml\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n  elasticsearch:\n    image: docker.elastic.co\u002Felasticsearch\u002Felasticsearch:8.11.0\n    environment:\n      - discovery.type=single-node\n      - xpack.security.enabled=false\n      - \"ES_JAVA_OPTS=-Xms1g -Xmx1g\"\n    ports:\n      - \"127.0.0.1:9200:9200\"\n    volumes:\n      - elasticsearch-data:\u002Fusr\u002Fshare\u002Felasticsearch\u002Fdata\n\n  logstash:\n    image: docker.elastic.co\u002Flogstash\u002Flogstash:8.11.0\n    volumes:\n      - .\u002Flogstash\u002Fpipeline:\u002Fusr\u002Fshare\u002Flogstash\u002Fpipeline\n      - .\u002Flogstash\u002Fconfig:\u002Fusr\u002Fshare\u002Flogstash\u002Fconfig\n    ports:\n      - \"127.0.0.1:5044:5044\"\n      - \"127.0.0.1:5000:5000\"\n    depends_on:\n      - elasticsearch\n\n  kibana:\n    image: docker.elastic.co\u002Fkibana\u002Fkibana:8.11.0\n    ports:\n      - \"127.0.0.1:5601:5601\"\n    environment:\n      - ELASTICSEARCH_HOSTS=http:\u002F\u002Felasticsearch:9200\n    depends_on:\n      - elasticsearch\n\n  filebeat:\n    image: docker.elastic.co\u002Fbeats\u002Ffilebeat:8.11.0\n    user: root\n    volumes:\n      - .\u002Ffilebeat\u002Ffilebeat.yml:\u002Fusr\u002Fshare\u002Ffilebeat\u002Ffilebeat.yml:ro\n      - \u002Fvar\u002Flib\u002Fdocker\u002Fcontainers:\u002Fvar\u002Flib\u002Fdocker\u002Fcontainers:ro\n      - \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock:ro\n    depends_on:\n      - logstash\n\nvolumes:\n  elasticsearch-data:\n```\n\n## Elasticsearch Configuration\n\n### Index Templates\n\n```json\nPUT _index_template\u002Flogs-template\n{\n  \"index_patterns\": [\"logs-*\"],\n  \"template\": {\n    \"settings\": {\n      \"number_of_shards\": 1,\n      \"number_of_replicas\": 1,\n      \"index.lifecycle.name\": \"logs-policy\"\n    },\n    \"mappings\": {\n      \"properties\": {\n        \"@timestamp\": { \"type\": \"date\" },\n        \"message\": { \"type\": \"text\" },\n        \"level\": { \"type\": \"keyword\" },\n        \"service\": { \"type\": \"keyword\" },\n        \"host\": { \"type\": \"keyword\" },\n        \"trace_id\": { \"type\": \"keyword\" }\n      }\n    }\n  }\n}\n```\n\n### Index Lifecycle Management\n\n```json\nPUT _ilm\u002Fpolicy\u002Flogs-policy\n{\n  \"policy\": {\n    \"phases\": {\n      \"hot\": {\n        \"min_age\": \"0ms\",\n        \"actions\": {\n          \"rollover\": {\n            \"max_size\": \"50GB\",\n            \"max_age\": \"1d\"\n          }\n        }\n      },\n      \"warm\": {\n        \"min_age\": \"7d\",\n        \"actions\": {\n          \"shrink\": { \"number_of_shards\": 1 },\n          \"forcemerge\": { \"max_num_segments\": 1 }\n        }\n      },\n      \"cold\": {\n        \"min_age\": \"30d\",\n        \"actions\": {\n          \"freeze\": {}\n        }\n      },\n      \"delete\": {\n        \"min_age\": \"90d\",\n        \"actions\": {\n          \"delete\": {}\n        }\n      }\n    }\n  }\n}\n```\n\n## Logstash Pipeline\n\n### Basic Pipeline\n\n```ruby\n# logstash\u002Fpipeline\u002Fmain.conf\ninput {\n  beats {\n    port => 5044\n  }\n  \n  tcp {\n    port => 5000\n    codec => json_lines\n  }\n}\n\nfilter {\n  # Parse JSON logs\n  if [message] =~ \u002F^\\{\u002F {\n    json {\n      source => \"message\"\n    }\n  }\n  \n  # Parse timestamp\n  date {\n    match => [\"timestamp\", \"ISO8601\", \"yyyy-MM-dd HH:mm:ss\"]\n    target => \"@timestamp\"\n  }\n  \n  # Add environment tag\n  mutate {\n    add_field => { \"environment\" => \"production\" }\n  }\n  \n  # Grok pattern for nginx logs\n  if [type] == \"nginx\" {\n    grok {\n      match => {\n        \"message\" => '%{IPORHOST:client_ip} - %{USER:user} \\[%{HTTPDATE:timestamp}\\] \"%{WORD:method} %{URIPATHPARAM:request} HTTP\u002F%{NUMBER:http_version}\" %{NUMBER:status} %{NUMBER:bytes}'\n      }\n    }\n  }\n}\n\noutput {\n  elasticsearch {\n    hosts => [\"elasticsearch:9200\"]\n    index => \"logs-%{+YYYY.MM.dd}\"\n  }\n}\n```\n\n### Advanced Filtering\n\n```ruby\nfilter {\n  # Parse application logs\n  grok {\n    match => {\n      \"message\" => \"%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \\[%{DATA:service}\\] %{GREEDYDATA:log_message}\"\n    }\n  }\n  \n  # Extract trace ID from message\n  if [log_message] =~ \u002Ftrace_id=\u002F {\n    grok {\n      match => { \"log_message\" => \"trace_id=%{UUID:trace_id}\" }\n    }\n  }\n  \n  # GeoIP lookup\n  if [client_ip] {\n    geoip {\n      source => \"client_ip\"\n      target => \"geoip\"\n    }\n  }\n  \n  # Drop debug logs in production\n  if [level] == \"DEBUG\" and [environment] == \"production\" {\n    drop {}\n  }\n  \n  # Enrich with lookup\n  translate {\n    field => \"status\"\n    destination => \"status_description\"\n    dictionary => {\n      \"200\" => \"OK\"\n      \"404\" => \"Not Found\"\n      \"500\" => \"Internal Server Error\"\n    }\n  }\n}\n```\n\n## Filebeat Configuration\n\n```yaml\n# filebeat\u002Ffilebeat.yml\nfilebeat.inputs:\n  - type: container\n    paths:\n      - '\u002Fvar\u002Flib\u002Fdocker\u002Fcontainers\u002F*\u002F*.log'\n    processors:\n      - add_docker_metadata:\n          host: \"unix:\u002F\u002F\u002Fvar\u002Frun\u002Fdocker.sock\"\n\n  - type: log\n    enabled: true\n    paths:\n      - \u002Fvar\u002Flog\u002Fnginx\u002F*.log\n    tags: [\"nginx\"]\n    fields:\n      type: nginx\n\noutput.logstash:\n  hosts: [\"logstash:5044\"]\n\nlogging.level: info\nlogging.to_files: true\nlogging.files:\n  path: \u002Fvar\u002Flog\u002Ffilebeat\n  name: filebeat\n  keepfiles: 7\n```\n\n## Elasticsearch Queries\n\n### Basic Queries\n\n```json\n\u002F\u002F Search all logs\nGET logs-*\u002F_search\n{\n  \"query\": {\n    \"match_all\": {}\n  }\n}\n\n\u002F\u002F Search by keyword\nGET logs-*\u002F_search\n{\n  \"query\": {\n    \"match\": {\n      \"message\": \"error\"\n    }\n  }\n}\n\n\u002F\u002F Filter by field\nGET logs-*\u002F_search\n{\n  \"query\": {\n    \"bool\": {\n      \"must\": [\n        { \"match\": { \"level\": \"ERROR\" } },\n        { \"range\": { \"@timestamp\": { \"gte\": \"now-1h\" } } }\n      ],\n      \"filter\": [\n        { \"term\": { \"service\": \"api-gateway\" } }\n      ]\n    }\n  }\n}\n```\n\n### Aggregations\n\n```json\n\u002F\u002F Count by log level\nGET logs-*\u002F_search\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"log_levels\": {\n      \"terms\": { \"field\": \"level\" }\n    }\n  }\n}\n\n\u002F\u002F Error rate over time\nGET logs-*\u002F_search\n{\n  \"size\": 0,\n  \"aggs\": {\n    \"errors_over_time\": {\n      \"date_histogram\": {\n        \"field\": \"@timestamp\",\n        \"fixed_interval\": \"5m\"\n      },\n      \"aggs\": {\n        \"error_count\": {\n          \"filter\": { \"term\": { \"level\": \"ERROR\" } }\n        }\n      }\n    }\n  }\n}\n```\n\n## Kibana Setup\n\n### Index Patterns\n\n1. Go to Stack Management → Index Patterns\n2. Create pattern: `logs-*`\n3. Set time field: `@timestamp`\n\n### Saved Searches\n\nCreate saved searches for common queries:\n- `level:ERROR` - All errors\n- `service:api-gateway AND level:ERROR` - API gateway errors\n- `response_time:>1000` - Slow requests\n\n### Visualizations\n\nCommon visualization types:\n- **Line Chart**: Error rate over time\n- **Pie Chart**: Distribution by log level\n- **Data Table**: Top error messages\n- **Metric**: Total error count\n\n### Dashboard Example\n\nCreate dashboard with:\n1. Total log count (Metric)\n2. Error rate trend (Line chart)\n3. Logs by service (Pie chart)\n4. Recent errors (Data table)\n5. Log stream (Discover panel)\n\n## Alerting\n\n### Watcher (X-Pack)\n\n```json\nPUT _watcher\u002Fwatch\u002Ferror_alert\n{\n  \"trigger\": {\n    \"schedule\": { \"interval\": \"5m\" }\n  },\n  \"input\": {\n    \"search\": {\n      \"request\": {\n        \"indices\": [\"logs-*\"],\n        \"body\": {\n          \"query\": {\n            \"bool\": {\n              \"must\": [\n                { \"match\": { \"level\": \"ERROR\" } },\n                { \"range\": { \"@timestamp\": { \"gte\": \"now-5m\" } } }\n              ]\n            }\n          }\n        }\n      }\n    }\n  },\n  \"condition\": {\n    \"compare\": { \"ctx.payload.hits.total.value\": { \"gt\": 100 } }\n  },\n  \"actions\": {\n    \"notify_slack\": {\n      \"webhook\": {\n        \"scheme\": \"https\",\n        \"host\": \"hooks.slack.com\",\n        \"port\": 443,\n        \"method\": \"post\",\n        \"path\": \"\u002Fservices\u002Fxxx\",\n        \"body\": \"{\\\"text\\\": \\\"High error rate detected: {{ctx.payload.hits.total.value}} errors in last 5 minutes\\\"}\"\n      }\n    }\n  }\n}\n```\n\n## Common Issues\n\n### Issue: High Disk Usage\n**Problem**: Elasticsearch consuming too much disk\n**Solution**: Implement ILM policies, reduce retention\n\n### Issue: Slow Searches\n**Problem**: Queries taking too long\n**Solution**: Optimize index settings, add more shards, use filters\n\n### Issue: Log Parsing Failures\n**Problem**: Logs not parsed correctly\n**Solution**: Test grok patterns, check for log format changes\n\n### Issue: Memory Pressure\n**Problem**: Elasticsearch OOM errors\n**Solution**: Increase heap size (max 50% of RAM), limit field data\n\n## Best Practices\n\n- Implement index lifecycle management\n- Use index templates for consistent mappings\n- Parse logs at ingestion time\n- Limit stored fields to reduce storage\n- Use data streams for time-series data\n- Monitor cluster health\n- Implement proper security (X-Pack)\n- Regular index maintenance\n\n## Related Skills\n\n- loki-logging (`loki-logging`) - Alternative logging stack\n- prometheus-grafana (`prometheus-grafana`) - Metrics monitoring\n- audit-logging (`audit-logging`) - Compliance logging\n\n## Limitations\n\n- Guidance executes against real environments: confirm target, blast radius, and rollback plan before applying anything.\n- Never deploy to production without explicit approval. Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\ngit status && git diff --stat\nkubectl diff -f manifest.yaml\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n",{"name":5,"risk":30,"source":49,"license":14,"category":50,"metadata":51,"date_added":54,"description":7,"source_repo":55,"source_type":33,"compatibility":56,"license_source":57},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills","devops",{"author":52,"version":53},"devops-skills","1.0","2026-09-20","BagelHole\u002FDevOps-Security-Agent-Skills","Requires the relevant platform CLIs (kubectl, helm, terraform, git, CI runners) and authorized access to the target environment. Docs-only; helper scripts and templates not bundled.","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE","7bf2279c8a65758319526a721d5c4b75683aec9c","skills\u002Fantigravity-elk-stack",3,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections","https:\u002F\u002Fgithub.com\u002Fboisenoise","2026-11-12 14:21:24",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add boisenoise\u002Fskills-collections --skill elk-stack",{"tool":70,"command":71},"bunx","bunx skills add boisenoise\u002Fskills-collections --skill elk-stack",{"tool":73,"command":74},"pnpm","pnpm dlx skills add boisenoise\u002Fskills-collections --skill elk-stack","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-elk-stack\u002FSKILL.md",true,[],[79,104,130,156,175,198],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":83,"licenseFileUrl":84,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":44},"01M6WNH92BHVFXHGPDZCPJ0AG0","web-access","Use Treg for public web or platform data only when existing search, browser and connected tools cannot cover the task, with explicit cost and data boundaries.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FSKILL.md",[],[88,36,89,90,91,92,93,94,95,96,97,25,98,99,31,30,100,101,102,103,26],"web","web access","official","development","browser","search","data","Tools","read","fetch","youtube","free tools","free","cover","normal","when",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":83,"licenseFileUrl":108,"sourceHtmlUrl":109,"categories":110,"keywords":114,"publishedAt":44},"01M6WNF9XAYAB2CZDDJBAKNM93","treg","Use the Treg CLI or MCP catalog to discover, price and call authorized external tools with team-scoped credentials and a user-approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FSKILL.md",[111],{"categoryNo":112,"categoryName":113,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[106,115,116,117,90,91,118,95,119,120,121,122,123,124,125,30,126,127,128,129,26],"MCP","cli","github","license","Budget","credentials","team","catalog","use","call","discover","external tools","with","scoped","blob",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":83,"licenseFileUrl":134,"sourceHtmlUrl":135,"categories":136,"keywords":142,"publishedAt":44},"01M6WN93MEAZ4E41DYAHJRPHQT","recruit","Turn a job description into an evidence-linked candidate shortlist through Treg, with job-related ranking and optional authorized business contact enrichment.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FSKILL.md",[137],{"categoryNo":138,"categoryName":139,"taxonomyType":140,"taxonomyTypeDesc":141},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[132,117,90,118,143,144,145,146,147,148,30,149,150,151,127,152,153,154,155,129,106,26],"https","email","enrichment","business","evidence","phone","ranking","post","job description","for","person","candidate","reason",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":83,"licenseFileUrl":160,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":44},"01M6WN8R5RXSMHM9B4D9FAFX42","rea-growth","Analyze a company’s public growth and content through Treg, distinguish observations from hypotheses, and produce an evidence-linked playbook within an approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FSKILL.md",[],[164,165,166,117,90,118,167,168,143,169,119,170,171,172,147,30,173,174,129,106,26],"growth","rea","rea growth","produce","content","playbook","marketing","analyze","public","observations","company",{"skillNo":176,"name":177,"nameZh":6,"description":178,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":83,"licenseFileUrl":179,"sourceHtmlUrl":180,"categories":181,"keywords":182,"publishedAt":44},"01M6WN2EVE3RQRGWAKBT4S7YT2","make-ugc","Create original AI UGC-style product videos through Treg: research hooks, approve a licensed presenter and voice, generate clips, add captions and report costs.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FSKILL.md",[],[183,184,117,185,90,186,118,187,188,189,190,191,30,192,193,194,195,196,197,129],"make","make ugc","research","create","Video","Captions","ads","short","hooks","head","style","niche","trending","talking-head","approve",{"skillNo":199,"name":200,"nameZh":6,"description":201,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":83,"licenseFileUrl":202,"sourceHtmlUrl":203,"categories":204,"keywords":205,"publishedAt":44},"01M6WN10ARAA63Y8K1YNGXJ2RM","lead-signals","Find and qualify public buying signals through Treg, rank fitting business accounts and optionally enrich authorized business contact information.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FSKILL.md",[],[206,207,208,117,90,118,209,210,146,211,212,30,213,214,215,216,217,218,219,129],"signals","lead","lead signals","how","find","ready","as","how to","qualify","people","information","enrich","changes","funding"]