imbi-plugin-logzio 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,72 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout plugin
14
+ uses: actions/checkout@v4
15
+ with:
16
+ path: imbi-plugin-logzio
17
+
18
+ - name: Checkout imbi-common
19
+ uses: actions/checkout@v4
20
+ with:
21
+ repository: AWeber-Imbi/imbi-common
22
+ path: imbi-common
23
+ ref: 3c89a42d3fc07f82d7215a253fd5b8860a3302be
24
+ token: ${{ secrets.GITHUB_TOKEN }}
25
+
26
+ - name: Set up uv
27
+ uses: astral-sh/setup-uv@v5
28
+ with:
29
+ python-version: "3.14"
30
+
31
+ - name: Wire imbi-common as path source
32
+ working-directory: imbi-plugin-logzio
33
+ run: |
34
+ printf '\n[tool.uv.sources]\nimbi-common = { path = "../imbi-common", editable = true }\n' >> pyproject.toml
35
+
36
+ - name: Install dependencies
37
+ working-directory: imbi-plugin-logzio
38
+ env:
39
+ UV_CONFIG_FILE: /dev/null
40
+ run: |
41
+ uv lock
42
+ uv sync
43
+
44
+ - name: Lint
45
+ working-directory: imbi-plugin-logzio
46
+ env:
47
+ UV_CONFIG_FILE: /dev/null
48
+ run: uv run ruff check src tests
49
+
50
+ - name: Format check
51
+ working-directory: imbi-plugin-logzio
52
+ env:
53
+ UV_CONFIG_FILE: /dev/null
54
+ run: uv run ruff format --check src tests
55
+
56
+ - name: Type check
57
+ working-directory: imbi-plugin-logzio
58
+ env:
59
+ UV_CONFIG_FILE: /dev/null
60
+ run: uv run basedpyright
61
+
62
+ - name: Tests with coverage
63
+ working-directory: imbi-plugin-logzio
64
+ env:
65
+ UV_CONFIG_FILE: /dev/null
66
+ run: uv run coverage run -m pytest tests/
67
+
68
+ - name: Coverage report
69
+ working-directory: imbi-plugin-logzio
70
+ env:
71
+ UV_CONFIG_FILE: /dev/null
72
+ run: uv run coverage report
@@ -0,0 +1,45 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ permissions:
7
+ id-token: write
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v6
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v5
20
+
21
+ - name: Set up Python
22
+ run: uv python install 3.14
23
+
24
+ - name: Build
25
+ run: uv build
26
+
27
+ - name: Upload dist
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment: pypi
37
+ steps:
38
+ - name: Download dist
39
+ uses: actions/download-artifact@v4
40
+ with:
41
+ name: dist
42
+ path: dist/
43
+
44
+ - name: Publish package
45
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,54 @@
1
+ name: Testing
2
+ on:
3
+ pull_request:
4
+ push:
5
+ branches: [ "main" ]
6
+ paths-ignore:
7
+ - 'docs/**'
8
+ - '*.md'
9
+ tags-ignore: [ "*" ]
10
+
11
+ jobs:
12
+ lint:
13
+ name: "Static Analysis"
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v5
18
+ - name: Install just
19
+ uses: extractions/setup-just@v2
20
+ with:
21
+ just-version: '1.47.1'
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v7
24
+ with:
25
+ enable-cache: true
26
+ - name: Run linters
27
+ run: just lint
28
+
29
+ test:
30
+ name: "Automated Tests"
31
+ runs-on: ubuntu-latest
32
+ strategy:
33
+ fail-fast: false
34
+ matrix:
35
+ python: [ "3.14" ]
36
+ steps:
37
+ - name: Checkout repository
38
+ uses: actions/checkout@v5
39
+ - name: Install just
40
+ uses: extractions/setup-just@v2
41
+ with:
42
+ just-version: '1.47.1'
43
+ - name: Install uv
44
+ uses: astral-sh/setup-uv@v7
45
+ with:
46
+ python-version: "${{ matrix.python }}"
47
+ enable-cache: true
48
+ - name: Test with python ${{ matrix.python }}
49
+ run: just test
50
+ - name: Upload Coverage
51
+ uses: codecov/codecov-action@v5
52
+ with:
53
+ files: ./build/coverage.xml
54
+ flags: unittests
@@ -0,0 +1,36 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-added-large-files
9
+ - id: check-merge-conflict
10
+ - id: check-toml
11
+ - id: debug-statements
12
+
13
+ - repo: https://github.com/astral-sh/ruff-pre-commit
14
+ rev: v0.14.6
15
+ hooks:
16
+ - id: ruff-check
17
+ args: [--fix]
18
+ - id: ruff-format
19
+
20
+ - repo: https://github.com/tombi-toml/tombi-pre-commit
21
+ rev: v0.7.25
22
+ hooks:
23
+ - id: tombi-format
24
+
25
+ - repo: local
26
+ hooks:
27
+ - id: mypy
28
+ name: mypy
29
+ language: system
30
+ types: [python]
31
+ pass_filenames: false
32
+ entry: uv
33
+ args:
34
+ - run
35
+ - mypy
36
+ - src
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Imbi
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: imbi-plugin-logzio
3
+ Version: 1.0.0
4
+ Summary: Logz.io logs plugin for Imbi
5
+ Author-email: "Gavin M. Roy" <gavinr@aweber.com>
6
+ License: BSD-3-Clause
7
+ License-File: LICENSE
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Natural Language :: English
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Requires-Python: >=3.14
15
+ Requires-Dist: httpx>=0.27
16
+ Requires-Dist: imbi-common>=0.8.4
17
+ Requires-Dist: pydantic>=2
18
+ Description-Content-Type: text/markdown
19
+
20
+ # imbi-plugin-logzio
21
+
22
+ Logz.io provider for the Imbi project logs tab, surfacing relevant logs without requiring search knowledge.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install imbi-plugin-logzio
28
+ ```
29
+
30
+ ## Configuration
31
+
32
+ Assign the plugin to a service application in Imbi. The following options and credentials are available.
33
+
34
+ ### Options
35
+
36
+ | Name | Label | Default | Description |
37
+ |---|---|---|---|
38
+ | `region` | Region | `us` | Logz.io account region. One of `us`, `eu`, `uk`, `au`, `ca`. |
39
+ | `base_query` | Base Query Template | — | Elasticsearch `query_string` applied as a must clause. Supports `${project_slug}`, `${org_slug}`, `${environment}`, `${project_id}`. |
40
+ | `timestamp_field` | Timestamp Field | `@timestamp` | Source field containing the log timestamp. |
41
+ | `message_field` | Message Field | `message` | Source field containing the log message. |
42
+ | `level_field` | Level Field | `level` | Source field containing the log severity level. |
43
+ | `timeout_seconds` | Request Timeout | `15` | Per-request timeout in seconds. |
44
+
45
+ ### Region → Hostname
46
+
47
+ | Region | API Host |
48
+ |---|---|
49
+ | `us` | `api.logz.io` |
50
+ | `eu` | `api-eu.logz.io` |
51
+ | `uk` | `api-uk.logz.io` |
52
+ | `au` | `api-au.logz.io` |
53
+ | `ca` | `api-ca.logz.io` |
54
+
55
+ ### Credentials
56
+
57
+ | Name | Description |
58
+ |---|---|
59
+ | `api_token` | Logz.io API token with search privileges (`X-API-TOKEN` header). |
60
+
61
+ ## Base Query Templates
62
+
63
+ Use `${variable}` placeholders to scope log searches to a project automatically:
64
+
65
+ ```text
66
+ kubernetes.namespace_name:${project_slug} AND env:${environment}
67
+ ```
68
+
69
+ Variables substituted at search time: `project_slug`, `org_slug`, `environment`, `project_id`. Unknown variables are rejected at configuration time.
70
+
71
+ ## Filter Operators
72
+
73
+ | Operator | Translation |
74
+ |---|---|
75
+ | `eq` | Elasticsearch `term` |
76
+ | `ne` | Elasticsearch `bool.must_not.term` |
77
+ | `contains` | `match_phrase` on the configured `message_field`; non-leading `wildcard` (`value*`) on other fields |
78
+ | `starts_with` | Elasticsearch `prefix` |
79
+ | `regex` | Elasticsearch `regexp` (patterns starting with `.*`, `*`, or `?` are rejected) |
80
+
81
+ ## Development
82
+
83
+ ```bash
84
+ # Clone alongside imbi-common
85
+ git clone https://github.com/AWeber-Imbi/imbi-plugin-logzio
86
+ git clone https://github.com/AWeber-Imbi/imbi-common
87
+
88
+ cd imbi-plugin-logzio
89
+ UV_CONFIG_FILE=/dev/null uv sync
90
+ UV_CONFIG_FILE=/dev/null uv run pytest tests/
91
+ UV_CONFIG_FILE=/dev/null uv run coverage run -m pytest tests/ && uv run coverage report
92
+ ```
@@ -0,0 +1,73 @@
1
+ # imbi-plugin-logzio
2
+
3
+ Logz.io provider for the Imbi project logs tab, surfacing relevant logs without requiring search knowledge.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install imbi-plugin-logzio
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Assign the plugin to a service application in Imbi. The following options and credentials are available.
14
+
15
+ ### Options
16
+
17
+ | Name | Label | Default | Description |
18
+ |---|---|---|---|
19
+ | `region` | Region | `us` | Logz.io account region. One of `us`, `eu`, `uk`, `au`, `ca`. |
20
+ | `base_query` | Base Query Template | — | Elasticsearch `query_string` applied as a must clause. Supports `${project_slug}`, `${org_slug}`, `${environment}`, `${project_id}`. |
21
+ | `timestamp_field` | Timestamp Field | `@timestamp` | Source field containing the log timestamp. |
22
+ | `message_field` | Message Field | `message` | Source field containing the log message. |
23
+ | `level_field` | Level Field | `level` | Source field containing the log severity level. |
24
+ | `timeout_seconds` | Request Timeout | `15` | Per-request timeout in seconds. |
25
+
26
+ ### Region → Hostname
27
+
28
+ | Region | API Host |
29
+ |---|---|
30
+ | `us` | `api.logz.io` |
31
+ | `eu` | `api-eu.logz.io` |
32
+ | `uk` | `api-uk.logz.io` |
33
+ | `au` | `api-au.logz.io` |
34
+ | `ca` | `api-ca.logz.io` |
35
+
36
+ ### Credentials
37
+
38
+ | Name | Description |
39
+ |---|---|
40
+ | `api_token` | Logz.io API token with search privileges (`X-API-TOKEN` header). |
41
+
42
+ ## Base Query Templates
43
+
44
+ Use `${variable}` placeholders to scope log searches to a project automatically:
45
+
46
+ ```text
47
+ kubernetes.namespace_name:${project_slug} AND env:${environment}
48
+ ```
49
+
50
+ Variables substituted at search time: `project_slug`, `org_slug`, `environment`, `project_id`. Unknown variables are rejected at configuration time.
51
+
52
+ ## Filter Operators
53
+
54
+ | Operator | Translation |
55
+ |---|---|
56
+ | `eq` | Elasticsearch `term` |
57
+ | `ne` | Elasticsearch `bool.must_not.term` |
58
+ | `contains` | `match_phrase` on the configured `message_field`; non-leading `wildcard` (`value*`) on other fields |
59
+ | `starts_with` | Elasticsearch `prefix` |
60
+ | `regex` | Elasticsearch `regexp` (patterns starting with `.*`, `*`, or `?` are rejected) |
61
+
62
+ ## Development
63
+
64
+ ```bash
65
+ # Clone alongside imbi-common
66
+ git clone https://github.com/AWeber-Imbi/imbi-plugin-logzio
67
+ git clone https://github.com/AWeber-Imbi/imbi-common
68
+
69
+ cd imbi-plugin-logzio
70
+ UV_CONFIG_FILE=/dev/null uv sync
71
+ UV_CONFIG_FILE=/dev/null uv run pytest tests/
72
+ UV_CONFIG_FILE=/dev/null uv run coverage run -m pytest tests/ && uv run coverage report
73
+ ```
@@ -0,0 +1,55 @@
1
+ [default]
2
+ [private]
3
+ @help:
4
+ just --list
5
+
6
+ [private]
7
+ ci: lint test
8
+
9
+ [doc("Set up your development environment")]
10
+ [group("Environment")]
11
+ setup:
12
+ uv sync --all-groups --all-extras --frozen
13
+ uv run pre-commit install --install-hooks --overwrite
14
+
15
+ [doc("Run tests")]
16
+ [group("Testing")]
17
+ test *FILES: setup
18
+ #!/usr/bin/env sh
19
+ set -e
20
+ if [ -z "{{ FILES }}" ]; then
21
+ uv run --env-file .env coverage run -m pytest tests
22
+ uv run coverage report
23
+ uv run coverage xml -o build/coverage.xml
24
+ else
25
+ uv run --env-file .env pytest {{ FILES }}
26
+ fi
27
+
28
+ [doc("Run linters")]
29
+ [group("Testing")]
30
+ lint: setup
31
+ uv run pre-commit run --all-files
32
+
33
+ [doc("Reformat code (optionally pass specific files)")]
34
+ [group("Development")]
35
+ format *FILES: setup
36
+ #!/usr/bin/env sh
37
+ if [ "{{ FILES }}" = '' ]; then
38
+ args='--all-files'
39
+ else
40
+ args='--files {{ FILES }}'
41
+ fi
42
+ uv run pre-commit run ruff-format $args
43
+ uv run pre-commit run tombi-format $args
44
+
45
+ [doc("Remove runtime development artifacts")]
46
+ [group("Environment")]
47
+ clean:
48
+ rm -f .coverage .env
49
+ rm -fR build
50
+
51
+ [confirm]
52
+ [doc("Remove caches, virtual env, and output files")]
53
+ [group("Environment")]
54
+ real-clean: clean
55
+ rm -fR .venv .*_cache dist
@@ -0,0 +1,119 @@
1
+ [project]
2
+ name = "imbi-plugin-logzio"
3
+ version = "1.0.0"
4
+ description = "Logz.io logs plugin for Imbi"
5
+ readme = "README.md"
6
+ requires-python = ">=3.14"
7
+ license = { text = "BSD-3-Clause" }
8
+ authors = [{ name = "Gavin M. Roy", email = "gavinr@aweber.com" }]
9
+ classifiers = [
10
+ "Development Status :: 5 - Production/Stable",
11
+ "Intended Audience :: Developers",
12
+ "Natural Language :: English",
13
+ "Operating System :: OS Independent",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.14",
16
+ ]
17
+ dependencies = [
18
+ "httpx>=0.27",
19
+ "imbi-common>=0.8.4",
20
+ "pydantic>=2",
21
+ ]
22
+
23
+ [project.entry-points."imbi.plugins"]
24
+ logzio = "imbi_plugin_logzio.plugin:LogzioPlugin"
25
+
26
+ [dependency-groups]
27
+ dev = [
28
+ "basedpyright",
29
+ "coverage[toml]",
30
+ "imbi-common[server,databases]",
31
+ "pre-commit",
32
+ "pytest",
33
+ "pytest-asyncio",
34
+ "respx",
35
+ "ruff~=0.14.6",
36
+ ]
37
+ dist = ["build", "twine", "wheel"]
38
+
39
+ [build-system]
40
+ requires = ["hatchling"]
41
+ build-backend = "hatchling.build"
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["src/imbi_plugin_logzio"]
45
+
46
+ [tool.coverage.report]
47
+ exclude_also = ["typing.TYPE_CHECKING"]
48
+ fail_under = 90
49
+ show_missing = true
50
+
51
+ [tool.coverage.run]
52
+ branch = true
53
+ source = ["src/imbi_plugin_logzio"]
54
+
55
+ [tool.pytest.ini_options]
56
+ asyncio_mode = "auto"
57
+ asyncio_default_fixture_loop_scope = "function"
58
+
59
+ [tool.pyright]
60
+ executionEnvironments = [
61
+ { root = "src" },
62
+ { root = "tests", reportPrivateUsage = false },
63
+ ]
64
+ deprecateTypingAliases = true
65
+ reportMissingSuperCall = "hint"
66
+ reportMissingTypeStubs = false
67
+ typeCheckingMode = "strict"
68
+
69
+ [tool.ruff]
70
+ line-length = 79
71
+ target-version = "py314"
72
+
73
+ [tool.ruff.format]
74
+ quote-style = "single"
75
+
76
+ [tool.ruff.lint]
77
+ select = [
78
+ "BLE",
79
+ "C4",
80
+ "C90",
81
+ "E",
82
+ "W",
83
+ "F",
84
+ "G",
85
+ "I",
86
+ "N",
87
+ "Q",
88
+ "S",
89
+ "ASYNC",
90
+ "B",
91
+ "DTZ",
92
+ "FURB",
93
+ "RUF",
94
+ "T20",
95
+ "UP",
96
+ ]
97
+ ignore = [
98
+ "ASYNC109", # timeout param passed to httpx, not asyncio.timeout
99
+ "N818",
100
+ "RSE",
101
+ "S105",
102
+ "TRY003",
103
+ "TRY400",
104
+ "UP047",
105
+ ]
106
+ flake8-quotes = { inline-quotes = "single" }
107
+
108
+ [tool.ruff.lint.mccabe]
109
+ max-complexity = 15
110
+
111
+ [tool.ruff.lint.per-file-ignores]
112
+ "tests/**/*.py" = ["S"]
113
+
114
+ [tool.uv]
115
+ default-groups = ["dev"]
116
+
117
+ [[tool.uv.index]]
118
+ url = "https://pypi.org/simple"
119
+ default = true
@@ -0,0 +1,3 @@
1
+ from imbi_plugin_logzio.plugin import LogzioPlugin
2
+
3
+ __all__ = ['LogzioPlugin']