CtrlK
BlogDocsLog inGet started
Tessl Logo

golikovichev/secure-log2test

Turn a Kibana JSON log export into a runnable pytest suite using the secure-log2test CLI. Use when the user has a Kibana or Elasticsearch JSON export of API traffic and wants a regression suite from production logs, when extracting test cases from staging traffic, when scrubbing auth headers or secret-looking body fields before logs leave the laptop, when bridging Kibana-captured requests into a pytest-based suite for CI, when the user mentions Kibana logs, Elasticsearch JSON export, log-to-test conversion, log replay tests, auth header redaction, PII in logs, or regression tests from production traffic.

92

1.00x
Quality

100%

Does it follow best practices?

Impact

93%

1.00x

Average score across 2 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

generator.pysecure_log2test/core/

import csv
import json
import logging
import re
from pathlib import Path

from jinja2 import Environment, FileSystemLoader, select_autoescape

from .parser import KibanaLogEntry, REDACTED


logger = logging.getLogger(__name__)


def _slugify(value):
    value = value.lower()
    value = re.sub(r"[^a-z0-9]+", "_", value)
    value = value.strip("_")
    return value or "endpoint"


def _python_repr(value):
    """Render value as a safe Python literal.

    Generated tests are executed by the user via pytest. Without repr()
    the template inlines log entry strings as raw Python source, so a
    captured URL containing a quote or backslash can produce invalid or
    arbitrary code. repr() escapes everything correctly and emits a
    quoted literal the parser will accept. For dicts and lists repr()
    also produces a valid Python literal.
    """
    return repr(value)


def _is_json_body(value):
    """Body should be sent as `json=` argument (dict or list)."""
    return isinstance(value, (dict, list))


def _is_string_body(value):
    """Body should be sent as `data=` argument (non-empty string)."""
    return isinstance(value, str) and bool(value)


class KibanaTestGenerator:
    def __init__(self, templates_dir):
        self.env = Environment(
            loader=FileSystemLoader(str(templates_dir)),
            # autoescape disabled because we render Python source, not
            # HTML. String safety comes from the python_repr filter
            # applied to every log-derived value in the template.
            autoescape=select_autoescape([]),
            trim_blocks=True,
            lstrip_blocks=True,
        )
        self.env.filters["slug"] = _slugify
        self.env.filters["python_repr"] = _python_repr
        self.env.tests["json_body"] = _is_json_body
        self.env.tests["string_body"] = _is_string_body

    def render(self, entries, base_url="", redact_marker=REDACTED):
        template = self.env.get_template("test_module.py.j2")
        cleaned = []
        for e in entries:
            if isinstance(e, KibanaLogEntry):
                cleaned.append(e)
            else:
                cleaned.append(KibanaLogEntry(**e))
        return template.render(
            entries=cleaned,
            base_url=base_url,
            redacted_marker=redact_marker,
        )

    def write(
        self,
        entries,
        output_path,
        base_url="",
        output_format="pytest",
        redact_marker=REDACTED,
    ):
        output_path = Path(output_path)
        output_path.parent.mkdir(parents=True, exist_ok=True)

        if output_format == "pytest":
            rendered = self.render(
                entries, base_url=base_url, redact_marker=redact_marker
            )
            output_path.write_text(rendered, encoding="utf-8")
        elif output_format == "json":
            self.write_json(entries, output_path)
        elif output_format == "csv":
            self.write_csv(entries, output_path)
        else:
            raise ValueError(f"Unsupported output format: {output_format}")

        logger.info("Wrote %d entries to %s", len(entries), output_path)
        return output_path

    def write_json(self, entries, output_path):
        """Write entries to JSON output. Note: templates arg is unused for non-pytest formats."""
        data = [e.model_dump() if isinstance(e, KibanaLogEntry) else e for e in entries]
        with open(output_path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)

    def write_csv(self, entries, output_path):
        """Write entries to CSV output. Note: templates arg is unused for non-pytest formats."""
        fieldnames = list(KibanaLogEntry.model_fields.keys())
        with open(output_path, "w", encoding="utf-8", newline="") as f:
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            for e in entries:
                row = e.model_dump() if isinstance(e, KibanaLogEntry) else e
                # Serialize dicts/lists to JSON strings for CSV compatibility
                row["headers"] = json.dumps(row.get("headers", {}), ensure_ascii=False)
                row["body"] = json.dumps(row.get("body"), ensure_ascii=False)
                writer.writerow(row)

CHANGELOG.md

CONTRIBUTING.md

README.md

REFERENCE.md

RELEASING.md

requirements.txt

SECURITY.md

SKILL.md

tessl.json

tile.json