{"id":27224750,"url":"https://github.com/clemcer/loggifly","last_synced_at":"2026-05-18T10:00:45.829Z","repository":{"id":277226156,"uuid":"916246515","full_name":"clemcer/loggifly","owner":"clemcer","description":"Monitor Docker Logs and send Notifications","archived":false,"fork":false,"pushed_at":"2025-04-08T20:17:17.000Z","size":3616,"stargazers_count":310,"open_issues_count":4,"forks_count":10,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-08T20:32:02.587Z","etag":null,"topics":["apprise","docker","docker-logs","logging","logs","monitoring","notifications","ntfy","server-events"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clemcer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-13T18:20:33.000Z","updated_at":"2025-04-08T14:47:32.000Z","dependencies_parsed_at":"2025-04-01T18:32:01.987Z","dependency_job_id":"7935b3ff-084d-4c23-9c3a-fd6de35fb7f1","html_url":"https://github.com/clemcer/loggifly","commit_stats":null,"previous_names":["clemcer/loggifly"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemcer%2Floggifly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemcer%2Floggifly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemcer%2Floggifly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemcer%2Floggifly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clemcer","download_url":"https://codeload.github.com/clemcer/loggifly/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248198878,"owners_count":21063627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apprise","docker","docker-logs","logging","logs","monitoring","notifications","ntfy","server-events"],"created_at":"2025-04-10T10:02:07.730Z","updated_at":"2026-05-18T10:00:43.378Z","avatar_url":"https://github.com/clemcer.png","language":"Python","funding_links":[],"categories":["Python","monitoring"],"sub_categories":[],"readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"clemcer/loggifly\"\u003e\n    \u003cimg src=\"/images/icon.png\" alt=\"Logo\" width=\"200\" height=\"auto\"\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\u003ch1 align=\"center\"\u003eLoggiFly\u003c/h1\u003e\n\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/clemcer/loggifly/issues\"\u003eReport Bug\u003c/a\u003e\n    \u003ca href=\"https://github.com/clemcer/loggifly/issues\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/p\u003e\n\n\u003cbr\u003e\n\n**LoggiFly** - A Lightweight Tool that monitors Docker Container Logs for predefined keywords or regex patterns and sends Notifications.\n\nGet instant alerts for security breaches, system errors, or custom patterns through your favorite notification channels. 🚀\n\n\n**Ideal For**:\n- ✅ Catching security breaches (e.g., failed logins in Vaultwarden)\n- ✅ Debugging crashes with attached log context\n- ✅ Restarting containers on specific errors or stopping them completely to avoid restart loops\n- ✅ Monitoring custom app behaviors (e.g., when a user downloads an audiobook on your Audiobookshelf server)\n\n\n\u003cdiv align=\"center\"\u003e\n   \u003cimg src=\"/images/vault_failed_login.gif\" alt=\"Failed Vaultwarden Login\" width=\"auto\" height=\"150\"\u003e\n\u003c/div\u003e\n\n---\n\n## Content\n\n- [Features](#-features)\n- [Screenshots](#-screenshots)\n- [Quick Start](#️-quick-start)\n- [Configuration Deep Dive](#-Configuration-Deep-Dive)\n  - [Basic config structure](#-basic-structure)\n  - [Environment Variables](#-environment-variables)\n- [Tips](#-tips)\n\n---\n\n## 🚀 Features\n\n- **🔍 Plain Text, Regex \u0026 Multi-Line Log Detection**: Catch simple keywords or complex patterns in log entries that span multiple lines.\n- **🚨 Ntfy/Apprise Alerts**: Send notifications directly to Ntfy or via Apprise to 100+ different services (Slack, Discord, Telegram).\n- **🔁 Trigger Stop/Restart**: A restart/stop of the monitored container can be triggered on specific critical keywords.\n- **⚙️ Fine-Grained Control**: Unique keywords and other settings (like ntfy topic/tags/priority) per container.\n- **📁 Log Attachments**: Automatically include a log file to the notification for context.\n- **⚡ Automatic Reload on Config Change**: The program automatically reloads the `config.yaml` when it detects that the file has been changed.\n\n---\n## 🖼 Screenshots\n\n\u003cdiv align=\"center\"\u003e\n   \u003cimg src=\"/images/abs_login.png\" alt=\"Audiobookshelf Login\" width=\"300\" height=\"auto\"\u003e\n   \u003cimg src=\"/images/vault_failed_login.png\" alt=\"Vaultwarden Login\" width=\"300\" height=\"auto\"\u003e\n   \u003cimg src=\"/images/abs_download.png\" alt=\"Audiobookshelf Download\" width=\"300\" height=\"auto\"\u003e\n  \u003cimg src=\"/images/ebook2audiobook.png\" alt=\"Ebook2Audiobook conversion finished\" width=\"300\" height=\"auto\"\u003e\n\n\u003c/div\u003e\n\n---\n\n## ⚡️ Quick start\n\n\nIn this quickstart only the most essential settings are covered, [here](#-Configuration-Deep-Dive) is a more detailed config walkthrough.\u003cbr\u003e\n\nChoose your preferred setup method - simple environment variables for basic use, or a YAML config for advanced control.\n- Environment variables allow for a simple setup and let you spin this thing up in a minute\n- With YAML you can use complex Regex patterns, have different keywords \u0026 other settings per container and set keywords that trigger a restart/stop of the container.\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e 🐋 \u003cstrong\u003eBasic Setup: Docker Compose (Environment Variables)\u003c/strong\u003e\u003c/summary\u003e\nIdeal for quick setup with minimal configuration\n\n```yaml\nversion: \"3.8\"\nservices:\n  loggifly:\n    image: ghcr.io/clemcer/loggifly:latest\n    container_name: loggifly\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n#      - ./config.yaml:/app/config.yaml  # Path to your config file (ignore if you are only using environment variables)\n    environment:\n      # Choose at least one notification service\n      NTFY_URL: \"https://ntfy.sh\"       # or your self-hosted instance\n      NTFY_TOPIC: \"your_topic\"          # e.g., \"docker_alerts\"\n      # Token or Username+Password In case you need authentication\n      # NTFY_TOKEN:\n      # NTFY_USERNAME:\n      # NTFY_PASSWORD:\n      APPRISE_URL: \"discord://...\"      # Apprise-compatible URL\n    \n      CONTAINERS: \"vaultwarden,audiobookshelf\"        # Comma-separated list\n      GLOBAL_KEYWORDS: \"error,failed login,password\"  # Basic keyword monitoring\n      GLOBAL_KEYWORDS_WITH_ATTACHMENT: \"critical\"     # Attaches a log file to the notification\n    restart: unless-stopped \n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e\u003cstrong\u003e 📜 Advanced Setup: YAML Configuration\u003c/strong\u003e\u003c/summary\u003e\n\nRecommended for granular control and regex patterns. \u003cbr\u003e\n\n**Step 1: Update Docker Compose**\n\nUncomment/add this line in your docker-compose.yml:\n```yaml\nvolumes:\n  - ./YOUR/CONFIG/FOLDER/config.yaml:/app/config.yaml  # 👈 Replace left side of the mapping with your local path\n```\n**Step 2: Create Config File**\n\nCreate the config.yaml in your chosen folder:\n```bash\nmkdir -p ./loggifly_config  # Example folder\ncd ./loggifly_config\ntouch config.yaml           # Create empty file\n```\n**Step 3: Configure Your config.yaml**\n\nAdd this minimal example config to the file you just created and edit it according to your needs.\u003cbr\u003e(If you want more options take a look at the more detailed [config walkthrough](#-Configuration-Deep-Dive) or at this [example config](/config.yaml)):\n```yaml\n# You have to configure at least one container.\ncontainers:\n  container-name:  # Exact container name\n  # Configure at least one type of keywords or use global keywords\n    keywords:\n      - error\n      - regex: (username|password).*incorrect  # Use regex patterns when you need them\n    # Attach a log file to the notification \n    keywords_with_attachment:\n      - warn\n    # Caution advised! These keywords will trigger a restart/stop of the container\n    action_keywords:\n      - stop: traceback\n      - restart: critical\n\n# Optional. These keywords are being monitored for all configured containers. There is an action_cooldown (see config deep dive)\nglobal_keywords:\n  keywords:\n    - failed\n  keywords_with_attachment:\n    - critical\n\nnotifications:     \n  # Configure either Ntfy or Apprise or both\n  ntfy:\n    url: http://your-ntfy-server  \n    topic: loggifly                   \n    token: ntfy-token               # Ntfy token in case you need authentication \n    username: john                  # Ntfy Username+Password in case you need authentication \n    password: 1234                  # Ntfy Username+Password in case you need authentication \n  apprise:\n    url: \"discord://webhook-url\"    # Any Apprise-compatible URL (https://github.com/caronc/apprise/wiki)\n```\n\u003c/details\u003e\u003cbr\u003e\n\n\n**When everything is configured start the container**\n\n\n```bash\ndocker compose up -d\n```\n\n---\n\n\n## 🤿 Configuration Deep Dive\n\n\nThe Quick Start only covered the essential settings, here is a more detailed walktrough of all the configuration options.\n\n\n### 📁 Basic Structure\n\nThe **`config.yaml`** file is divided into four main sections:\n\n1. **`settings`**: Global settings like cooldowns and log levels. (_Optional since they all have default values_)\n2. **`notifications`**: Configure Ntfy (_URL, Topic, Token, Priority and Tags_) and/or your Apprise URL\n3. **`containers`**: Define which Containers to monitor and their specific Keywords (_plus optional settings_).\n4. **`global_keywords`**: Keywords that apply to _all_ monitored Containers.\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e\u003cstrong\u003e ⚙️ Settings \u003c/strong\u003e\u003c/summary\u003e\n\n```yaml\n# These are the default settings\nsettings:          \n  log_level: INFO               # DEBUG, INFO, WARNING, ERROR\n  notification_cooldown: 5      # Seconds between alerts for same keyword (per container)\n  action_cooldown: 300          # Cooldown period (in seconds) before the next container action can be performed. Maximum is always at least 60s.\n  attachment_lines: 20          # Number of Lines to include in log attachments\n  multi_line_entries: True      # Monitor and catch multi-line log entries instead of going line by line. \n  reload_config: True        # When the config file is changed the program reloads the config\n  disable_start_message: False  # Suppress startup notification\n  disable_shutdown_message: False  # Suppress shutdown notification\n  disable_config_reload_message: False   # Suppress config reload notification\n```\n\n\u003c/details\u003e\n\n\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e\u003cstrong\u003e 📭 notifications \u003c/strong\u003e\u003c/summary\u003e\n\n```yaml\nnotifications:                       \n  # At least one of the two (Ntfy/Apprise) is required.\n  ntfy:\n    url: http://your-ntfy-server    # Required. The URL of your Ntfy instance\n    topic: loggifly.                # Required. the topic for Ntfy\n    token: ntfy-token               # Ntfy token in case you need authentication \n    username: john                  # Ntfy Username+Password in case you need authentication \n    password: 1234                  # Ntfy Username+Password in case you need authentication \n    priority: 3                     # Ntfy priority (1-5)\n    tags: kite,mag                  # Ntfy tags/emojis \n  apprise:\n    url: \"discord://webhook-url\"    # Any Apprise-compatible URL (https://github.com/caronc/apprise/wiki)\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e\u003cstrong\u003e 🐳 containers \u003c/strong\u003e\u003c/summary\u003e\n\n```yaml\ncontainers:\n  container-name:     # Must match exact container_name\n    # The next 5 settings are optional. They override the respective global setting for this container \n    ntfy_topic: your_topic\n    ntfy_tags: \"tag1, tag2\"     \n    ntfy_priority: 4            \n    attachment_lines: 10        \n    notification_cooldown: 10   \n    # Configure at least one type of keywords or use global keywords\n    keywords:                                 \n      - error                                  # Simple text matches\n      - regex: (username|password).*incorrect  # Use regex patterns when you need them\n    # When one of these keywords is found a logfile is attached to the notification\n    keywords_with_attachment:\n      - critical\n\n    # action_keywords will trigger a restart/stop of the container and can only be set per container\n    action_keywords:    # restart \u0026 stop are the only supported actions and have to be specified before every keyword\n      - stop: traceback\n      - restart:\n          regex: critical.*failed # this is how to set regex patterns for action_keywords\n    action_cooldown: 300 # 300s is the default time that has to pass until the next action can be triggered (minimum value is always 60)\n\n# If you have configured global_keywords and don't need container specific settings you can define the container name and leave the rest blank\n  another-container-name:\n```\n\n \u003c/details\u003e\n\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e\u003cstrong\u003e 🌍 global_keywords \u003c/strong\u003e\u003c/summary\u003e\n\n```yaml\n# This section is optional.\n# These keywords are being monitored for all containers. \nglobal_keywords:              \n  keywords:\n    - error\n  keywords_with_attachment:  # When one of these keywords is found a logfile is attached\n    - regex: (critical|error)\n```\n\n\u003c/details\u003e\n\n[Here](/config.yaml) you can find a full example config.\n\n\n### 🍀 Environment Variables\n\nExcept for `restart_keywords`, container specific settings and regex patterns you can configure most settings via docker environment variables.\n\n\u003cdetails\u003e\u003csummary\u003e\u003cem\u003eClick to expand:\u003c/em\u003e\u003cstrong\u003e Environment Variables \u003c/strong\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\n| Variables                         | Description                                              | Default  |\n|-----------------------------------|----------------------------------------------------------|----------|\n| `NTFY_URL`                      | URL of your Ntfy server instance                           | _N/A_    |\n| `NTFY_TOKEN`                    | Authentication token for Ntfy in case you need authentication.      | _N/A_    |\n| `NTFY_USERNAME`                 | Ntfy Username in case you need authentication.             | _N/A_    |\n| `NTFY_PASSWORD`                 | Ntfy password in case you need authentication.             | _N/A_    |\n| `NTFY_TOPIC`                    | Notification topic for Ntfy.                               | _N/A_  |\n| `NTFY_TAGS`                     | Ntfy [Tags/Emojis](https://docs.ntfy.sh/emojis/) for ntfy notifications. | kite,mag  |\n| `NTFY_PRIORITY`                 | Notification [priority](https://docs.ntfy.sh/publish/?h=priori#message-priority) for ntfy messages.                 | 3 / default |\n| `APPRISE_URL`                   | Any [Apprise-compatible URL](https://github.com/caronc/apprise/wiki)  | _N/A_    |\n| `CONTAINERS`                    | A comma separated list of containers. These are added to the containers from the config.yaml (if you are using one).| _N/A_     |\n| `GLOBAL_KEYWORDS`       | Keywords that will be monitored for all containers. Overrides `global_keywords.keywords` from the config.yaml.| _N/A_     |\n| `GLOBAL_KEYWORDS_WITH_ATTACHMENT`| Notifications triggered by these global keywords have a logfile attached. Overrides `global_keywords.keywords_with_attachment` from the config.yaml.| _N/A_     |\n| `NOTIFICATION_COOLDOWN`         | Cooldown period (in seconds) per container per keyword before a new message can be sent  | 5        | \n| `ACTION_COOLDOWN`         | Cooldown period (in seconds) before the next container action can be performed. Maximum is always at least 60s. (`action_keywords` are only configurable in YAML)  | 300        |\n| `LOG_LEVEL`                     | Log Level for LoggiFly container logs.                    | INFO     |\n| `MULTI_LINE_ENTRIES`            | When enabled the program tries to catch log entries that span multiple lines.\u003cbr\u003eIf you encounter bugs or you simply don't need it you can disable it.| True     |\n| `ATTACHMENT_LINES`              | Define the number of Log Lines in the attachment file     | 20     |\n| `RELOAD_CONFIG`               | When the config file is changed the program reloads the config | True  |\n| `DISBLE_START_MESSAGE`          | Disable startup message.                                  | False     |\n| `DISBLE_SHUTDOWN_MESSAGE`       | Disable shutdown message.                                 | False     |\n| `DISABLE_CONFIG_RELOAD_MESSAGE`       | Disable message when the config file is reloaded.| False     |\n\n\u003c/details\u003e\n\n---\n\n## 💡 Tips\n\n1. Ensure containers names **exactly match** your Docker **container names**. \n    - Find out your containers names: ```docker ps --format \"{{.Names}}\" ```\n    - 💡 Pro Tip: Define the `container_name:` in your compose files.\n2. **`action_keywords`** can not be set globally and only in the config.yaml. `action_cooldown` is always at least 60s and defaults to 300s\n3. **Test Regex Patterns**: Validate patterns at [regex101.com](https://regex101.com) before adding them to your config.\n4. When using a **Docker Socket Proxy** the log stream connection drops every ~10 minutes for whatever reason. LoggiFly simply resets the connection. This works but using a proxy is not officially recommended yet until I am sure everything works flawlessly. If you notice any bugs let me know!\n5. **Troubleshooting Multi-Line Log Entries**. If LoggiFly only catches single lines from log entries that span over multiple lines:\n    - Wait for Patterns: LoggiFly needs to process a few lines in order to detect the pattern the log entries start with (e.g. timestamps/log level)\n    - Unrecognized Patterns: If issues persist, open an issue and share the affected log samples\n\n---\n\n## License\n[MIT](https://github.com/clemcer/LoggiFly/blob/main/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclemcer%2Floggifly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclemcer%2Floggifly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclemcer%2Floggifly/lists"}