[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6P28EN2C4DXFP834EAG1NAB":3,"skill-same:01M6P28EN2C4DXFP834EAG1NAB":76},{"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":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":31,"commitSha":57,"skillDirectory":58,"forksCount":13,"repositoryHtmlUrl":59,"repositoryHomepageUrl":6,"ownerHtmlUrl":60,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":61,"install":62,"resources":75},"01M6P28EN2C4DXFP834EAG1NAB","elk-stack",null,"Deploy and manage the ELK Stack (Elasticsearch, Logstash, Kibana) for log aggregation and analysis.","duc-duy-1612\u002FOnline-Delivery-Systems-Web","duc-duy-1612","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F192231384?v=4","01M6NSDKQQDKVTHZ8DZMZ1VYY6","01M6NSDKW8DDVTQHBT1HBDDJPT",0,"MIT","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Felk-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],"elk stack","stack","only","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## 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      - \"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      - \"5044:5044\"\n      - \"5000:5000\"\n    depends_on:\n      - elasticsearch\n\n  kibana:\n    image: docker.elastic.co\u002Fkibana\u002Fkibana:8.11.0\n    ports:\n      - \"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## 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      - \"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      - \"5044:5044\"\n      - \"5000:5000\"\n    depends_on:\n      - elasticsearch\n\n  kibana:\n    image: docker.elastic.co\u002Fkibana\u002Fkibana:8.11.0\n    ports:\n      - \"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":29,"source":48,"license":14,"category":49,"metadata":50,"date_added":53,"description":7,"source_repo":54,"source_type":32,"compatibility":55,"license_source":56},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills","devops",{"author":51,"version":52},"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","f3312ba749561b6159f477dbfc9313c875d40a56",".agents\u002Fskills_archive\u002Felk-stack","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612","2026-10-25 23:50:58",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill elk-stack",{"tool":68,"command":69},"bunx","bunx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill elk-stack",{"tool":71,"command":72},"pnpm","pnpm dlx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill elk-stack","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Felk-stack\u002FSKILL.md",true,[],[77,96,120,145,173,197],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":84,"publishedAt":43},"01M6Q0FA5FZ410Z33Z3TFQ4DBA","zero-trust","Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzero-trust\u002FSKILL.md",[83],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[85,86,87,88,89,90,79,91,38,35,92,25,32,31,93,29,94,28,26,95],"ZeRO","trust","zero trust","architecture","assessment","verification","segmentation","configure","active","scope","implementing",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":43},"01M6Q0F1YZJW3KX5FBKEVZ8CV4","zcode-delegate","Delegate coding tasks to the Z.AI ZCode CLI only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzcode-delegate\u002FSKILL.md",[],[103,104,105,106,107,108,109,110,111,112,113,114,115,25,116,32,117,118,29,119],"delegate","zcode","zcode delegate","review","cli","orchestration","tasks","run","Bash","model","node","read","orchestrator","files","desktop app","app","agent-orchestration",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":43},"01M6Q0ETK41VGNMYEXW0T00AJN","youtube-transcript","Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript\u002FSKILL.md",[],[127,128,129,130,131,132,133,134,135,136,137,138,139,32,31,140,141,142,143,144],"transcript","youtube transcript","youtube","safe","github","codex","research","license","https","text","fetch","tooling","clean","local","output","deepapi","youtube transcripts","blob",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":162,"publishedAt":43},"01M6Q0EPPH2PVMDW40017F8WX0","youtube-transcript-skills","Fetch YouTube video transcripts, search videos\u002Fchannels, browse channels, and extract playlists via the getyoutubetranscript.com API - free tier, no card required.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript-skills\u002FSKILL.md",[151,154,157],{"categoryNo":152,"categoryName":153,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":155,"categoryName":156,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":158,"categoryName":159,"taxonomyType":160,"taxonomyTypeDesc":161},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[127,128,129,163,130,164,131,132,134,165,166,167,168,137,169,32,31,170,171,172],"youtube transcript skills","gemini","search","api","Video","browse","api-integration","free","card","channels",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":183,"publishedAt":43},"01M6Q0EAB96PX83W5PTE8A0R8D","youtube-notetaker","Turn YouTube talks into local study notes with slides, transcripts, editable annotations, and a markdown-backed viewer.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-notetaker\u002FSKILL.md",[179,182],{"categoryNo":180,"categoryName":181,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":155,"categoryName":156,"taxonomyType":20,"taxonomyTypeDesc":21},[129,184,185,107,130,186,187,188,189,134,167,190,191,192,193,31,194,140,195,196],"youtube notetaker","notetaker","workflow","official","notes","code","markdown","slides","annotations","README","study","dair-academy","viewer",{"skillNo":198,"name":199,"nameZh":6,"description":200,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":201,"categories":202,"keywords":204,"publishedAt":43},"01M6Q0E55F0GW5MX48V8HXS8B5","youtube-full","Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-full\u002FSKILL.md",[203],{"categoryNo":152,"categoryName":153,"taxonomyType":20,"taxonomyTypeDesc":21},[205,129,206,207,130,164,165,208,209,166,167,168,137,210,169,32,31,170,211,143],"youtube full","full","google","server","dlp","credits","automatic"]