Sign in

    moonlogfmt-lens

    Parse, contract-check, redact, profile, and diff logfmt data in MoonBit

    logfmt
    logs
    schema
    redaction
    drift
    moonbit
    Download zip
    Author
    Version
    0.2.2
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    19

    #MoonLogfmt Lens

    MoonLogfmt Lens is a MoonBit-native data-contract and quality toolkit for logfmt records. It parses existing log text, classifies semantic values, checks executable contracts, removes sensitive data, profiles batches, and explains schema drift without introducing a logging framework or telemetry stack.

    The package is designed for CI pipelines, command-line tools, support bundles, build logs, and service diagnostics. It has no external runtime dependencies and keeps all analysis deterministic across MoonBit targets.

    #Why This Exists

    Human-readable key/value logs are easy to emit but difficult to govern. Duplicate keys can hide values, a field can silently change from an integer to text, newly added fields can leak credentials, and one release can drift away from the schema observed in the previous release.

    MoonLogfmt Lens answers five separate questions:

    • Is the record syntactically valid and unambiguous?
    • Do its fields satisfy an executable log contract?
    • Does it contain credentials, personal data, payment data, or network identity?
    • What value-free shapes and semantic types occur in a batch?
    • Did the current batch drift materially from a known-good baseline?

    #Install

    moon add sqhyyy/moonlogfmt-lens

    The public repository is prepared for sqhyyy/moonlogfmt-lens, and the Mooncakes owner is sqhyyy.

    #Parse And Audit

    let parsed = @lens.parse(
    "level=info msg=\"service ready\" request_id=req-42",
    )

    if parsed.is_valid() {
    println(parsed.get("msg"))
    println(parsed.normalized())
    }

    let audit = @lens.audit_line_with_policy(
    "level=warn msg=one msg=two dry_run",
    @lens.AuditPolicy::ci(),
    )
    println(audit.text_report())

    The scanner supports bare values, quoted values, common escapes, explicit blank values, and flag fields. It preserves field order and offsets and reports malformed keys, unexpected equals signs, bare quotes, and unterminated strings.

    #Semantic Values

    inspect(@lens.classify_value("503"), content="ValueInteger")
    inspect(@lens.classify_value("1.5s"), content="ValueDuration")
    inspect(@lens.classify_value("2026-07-29T12:30:00Z"), content="ValueTimestamp")

    The deterministic classifier recognizes flags, blanks, booleans, integers, decimals, durations, byte sizes, timestamps, IPv4 values, UUIDs, email addresses, hexadecimal values, identifiers, and free text. These types form the shared vocabulary used by contract inference and drift analysis.

    #Executable Contracts

    let contract = @lens.LogContract::new(
    "api-service",
    [
    @lens.FieldRule::typed("level", @lens.ValueIdentifier, required=true)
    .with_allowed_values(["info", "warn", "error"]),
    @lens.FieldRule::text("msg", required=true).with_max_length(240),
    @lens.FieldRule::typed("status", @lens.ValueInteger),
    @lens.FieldRule::typed("duration", @lens.ValueDuration),
    ],
    unknown_fields=@lens.UnknownReject,
    )

    let report = @lens.validate_contract(
    "level=info msg=ready status=200 duration=12ms",
    contract,
    )
    println(report.decision())

    Contracts support required fields, semantic types, blank/flag controls, maximum lengths, controlled vocabularies, record field limits, duplicate rejection, and allow/warn/reject policies for unknown fields. Built-in service and CI contracts are available for quick adoption.

    #Schema Inference

    let inference = @lens.infer_schema([
    "level=info status=200 duration=12ms",
    "level=warn status=503 duration=1.5s",
    "level=info status=201 duration=9ms",
    ])

    println(inference.text_report())
    let candidate = inference.contract()

    Inference reports field prevalence, type distribution, dominant type, confidence, distinct sample values, and observed maximum length. It produces a candidate contract while limiting enum inference to genuinely categorical fields such as level, environment, state, and outcome.

    #Privacy-Safe Logs

    let result = @lens.redact_line(
    "level=info email=user@example.com api_token=secret peer=10.0.0.8",
    policy=@lens.RedactionPolicy::strict(),
    )

    println(result.safe_line())
    println(result.json_report())

    Privacy analysis combines key-aware rules with value-aware detection for bearer credentials, provider access keys, three-segment tokens, private-key markers, email addresses, formatted phone numbers, checksum-valid payment cards, high-entropy secrets, and optional IP-address protection.

    Redaction modes include full masking, last-four masking, and deterministic stable tokens. Reports never serialize the original sensitive value.

    #Batch Profiles

    let batch = @lens.analyze_batch(
    [
    "level=info msg=ready status=200",
    "level=warn msg=slow status=503",
    ],
    policy=@lens.BatchPolicy::ci(),
    )

    let decision = @lens.evaluate_batch(
    batch,
    policy=@lens.BatchGatePolicy::ci(),
    )
    println(decision.label())

    Batch analysis provides valid/invalid rates, risk bands, aggregate scores, field profiles, and value-free structural clusters. Canonical shapes are independent of field order, and stable fingerprints allow logs to be compared without retaining their concrete values.

    Batch gates support invalid-line budgets, high-risk budgets, average risk limits, shape-cardinality limits, and required-key prevalence.

    #Drift Detection

    let baseline = @lens.analyze_batch([
    "level=info msg=ready status=200 duration=12ms",
    "level=warn msg=slow status=503 duration=80ms",
    ])

    let current = @lens.analyze_batch([
    "level=info msg=ready status=ok region=us",
    "level=warn msg=slow status=failed region=eu",
    ])

    let drift = @lens.compare_batches(
    baseline,
    current,
    policy=@lens.DriftPolicy::ci(),
    )
    println(drift.text_report())

    Drift findings cover added and removed fields, semantic type changes, type confidence drops, prevalence changes, value-length growth, new and retired shapes, invalid-rate regressions, and aggregate-risk regressions. A known-good batch can also be frozen into a reusable LogContract.

    #CLI

    moon run cmd/main -- audit level=info msg="service ready" moon run cmd/main -- contract level=info msg=ready service=api moon run cmd/main -- privacy level=info api_token=secret moon run cmd/main -- profile status=503 duration=12ms moon run cmd/main -- template level=info msg=ready status=200

    Omitting the mode keeps compatibility with the original audit command.

    #Runnable Examples

    moon run examples/basic moon run examples/advanced moon run examples/privacy moon run examples/drift

    The advanced example infers and freezes a baseline contract. The privacy example demonstrates stable-token redaction. The drift example intentionally introduces a field-type regression, a removed field, a new field, a new shape, and malformed input.

    #Verification

    moon fmt moon fmt --check moon info moon check --target all --deny-warn moon build --target all moon test --target all --deny-warn moon package --list

    The current suite contains 95 tests covering parsing, auditing, semantic classification, contracts, inference, redaction, batch gates, structural fingerprints, and drift reports. All 95 tests pass on the wasm, wasm-gc, js, and native targets.

    #Boundaries

    MoonLogfmt Lens consumes in-memory logfmt records. It does not emit application logs, tail files, collect telemetry, export OpenTelemetry data, parse JSON, or replace logging frameworks. File readers, network collectors, and dashboards can build on top of the dependency-free core.

    #Contributing

    Development and verification instructions are available in CONTRIBUTING.md.

    #License

    Apache-2.0.

    AuditPolicy

    pub struct AuditPolicy {
    max_fields : Int
    max_value_length : Int
    flag_duplicate_keys : Bool
    flag_blank_values : Bool
    flag_flag_fields : Bool
    required_keys : Array[String]
    } derive(
    Debug
    )

    AuditPolicy::ci

    AuditPolicy::default

    fn AuditPolicy::default() -> AuditPolicy

    AuditPolicy::relaxed

    fn AuditPolicy::relaxed() -> AuditPolicy

    AuditPolicy::with_required_keys

    fn AuditPolicy::with_required_keys(self : AuditPolicy, keys : Array[String]) -> AuditPolicy

    AuditReport

    pub struct AuditReport {
    parsed : ParseResult
    findings : Array[Finding]
    } derive(
    Debug
    )

    AuditReport::count_severity

    fn AuditReport::count_severity(self : AuditReport, severity : Severity) -> Int

    AuditReport::critical_count

    fn AuditReport::critical_count(self : AuditReport) -> Int

    AuditReport::finding_count

    fn AuditReport::finding_count(self : AuditReport) -> Int

    AuditReport::findings

    fn AuditReport::findings(self : AuditReport) -> Array[Finding]

    AuditReport::info_count

    fn AuditReport::info_count(self : AuditReport) -> Int

    AuditReport::json_report

    fn AuditReport::json_report(self : AuditReport) -> String

    AuditReport::parsed

    fn AuditReport::parsed(self : AuditReport) -> ParseResult

    AuditReport::recommended_action

    fn AuditReport::recommended_action(self : AuditReport) -> String

    AuditReport::risk_level

    fn AuditReport::risk_level(self : AuditReport) -> String

    AuditReport::risk_score

    fn AuditReport::risk_score(self : AuditReport) -> Int

    AuditReport::text_report

    fn AuditReport::text_report(self : AuditReport) -> String

    AuditReport::warning_count

    fn AuditReport::warning_count(self : AuditReport) -> Int

    BatchDecision

    pub struct BatchDecision {
    accepted : Bool
    reasons : Array[String]
    } derive(Eq,
    Debug
    )

    BatchDecision::accepted

    fn BatchDecision::accepted(self : BatchDecision) -> Bool

    BatchDecision::label

    fn BatchDecision::label(self : BatchDecision) -> String

    BatchDecision::reasons

    fn BatchDecision::reasons(self : BatchDecision) -> Array[String]

    BatchDecision::text_report

    fn BatchDecision::text_report(self : BatchDecision) -> String

    BatchGatePolicy

    pub struct BatchGatePolicy {
    max_invalid_percent : Int
    max_high_risk_percent : Int
    max_average_risk_score : Int
    reject_shape_overflow : Bool
    required_keys : Array[String]
    min_required_prevalence : Int
    } derive(Eq,
    Debug
    )

    BatchGatePolicy::ci

    BatchGatePolicy::default

    BatchGatePolicy::with_error_budget

    fn BatchGatePolicy::with_error_budget(self : BatchGatePolicy, max_invalid_percent : Int, max_high_risk_percent : Int) -> BatchGatePolicy

    BatchGatePolicy::with_required_keys

    fn BatchGatePolicy::with_required_keys(self : BatchGatePolicy, required_keys : Array[String], min_prevalence? : Int) -> BatchGatePolicy

    BatchPolicy

    pub struct BatchPolicy {
    audit_policy : AuditPolicy
    skip_blank_lines : Bool
    max_distinct_shapes : Int
    } derive(
    Debug
    )

    Controls batch analysis without introducing file-system or process I/O.

    BatchPolicy::ci

    BatchPolicy::default

    fn BatchPolicy::default() -> BatchPolicy

    BatchPolicy::exploratory

    fn BatchPolicy::exploratory() -> BatchPolicy

    BatchPolicy::with_audit_policy

    fn BatchPolicy::with_audit_policy(self : BatchPolicy, audit_policy : AuditPolicy) -> BatchPolicy

    BatchPolicy::with_blank_lines

    fn BatchPolicy::with_blank_lines(self : BatchPolicy, skip_blank_lines : Bool) -> BatchPolicy

    BatchPolicy::with_shape_limit

    fn BatchPolicy::with_shape_limit(self : BatchPolicy, max_distinct_shapes : Int) -> BatchPolicy

    BatchReport

    pub struct BatchReport {
    input_lines : Int
    processed_lines : Int
    skipped_blank_lines : Int
    valid_lines : Int
    invalid_lines : Int
    clean_lines : Int
    low_risk_lines : Int
    medium_risk_lines : Int
    high_risk_lines : Int
    aggregate_risk_score : Int
    reviews : Array[LineReview]
    profiles : Array[FieldProfile]
    shapes : Array[ShapeStat]
    shape_limit_exceeded : Bool
    } derive(
    Debug
    )

    BatchReport::aggregate_risk_score

    fn BatchReport::aggregate_risk_score(self : BatchReport) -> Int

    BatchReport::average_risk_score

    fn BatchReport::average_risk_score(self : BatchReport) -> Int

    BatchReport::clean_lines

    fn BatchReport::clean_lines(self : BatchReport) -> Int

    BatchReport::high_risk_lines

    fn BatchReport::high_risk_lines(self : BatchReport) -> Int

    BatchReport::high_risk_percent

    fn BatchReport::high_risk_percent(self : BatchReport) -> Int

    BatchReport::input_lines

    fn BatchReport::input_lines(self : BatchReport) -> Int

    BatchReport::invalid_lines

    fn BatchReport::invalid_lines(self : BatchReport) -> Int

    BatchReport::invalid_percent

    fn BatchReport::invalid_percent(self : BatchReport) -> Int

    BatchReport::json_report

    fn BatchReport::json_report(self : BatchReport) -> String

    BatchReport::low_risk_lines

    fn BatchReport::low_risk_lines(self : BatchReport) -> Int

    BatchReport::medium_risk_lines

    fn BatchReport::medium_risk_lines(self : BatchReport) -> Int

    BatchReport::most_common_shape

    fn BatchReport::most_common_shape(self : BatchReport) -> ShapeStat?

    BatchReport::processed_lines

    fn BatchReport::processed_lines(self : BatchReport) -> Int

    BatchReport::profile_for

    fn BatchReport::profile_for(self : BatchReport, key : String) -> FieldProfile?

    BatchReport::profiles

    fn BatchReport::profiles(self : BatchReport) -> Array[FieldProfile]

    BatchReport::reviews

    fn BatchReport::reviews(self : BatchReport) -> Array[LineReview]

    BatchReport::shape_count

    fn BatchReport::shape_count(self : BatchReport) -> Int

    BatchReport::shape_for_fingerprint

    fn BatchReport::shape_for_fingerprint(self : BatchReport, fingerprint : String) -> ShapeStat?

    BatchReport::shape_limit_exceeded

    fn BatchReport::shape_limit_exceeded(self : BatchReport) -> Bool

    BatchReport::shapes

    fn BatchReport::shapes(self : BatchReport) -> Array[ShapeStat]

    BatchReport::skipped_blank_lines

    fn BatchReport::skipped_blank_lines(self : BatchReport) -> Int

    BatchReport::text_report

    fn BatchReport::text_report(self : BatchReport) -> String

    BatchReport::valid_lines

    fn BatchReport::valid_lines(self : BatchReport) -> Int

    ContractReport

    pub struct ContractReport {
    contract_name : String
    parsed : ParseResult
    violations : Array[ContractViolation]
    } derive(
    Debug
    )

    ContractReport::contract_name

    fn ContractReport::contract_name(self : ContractReport) -> String

    ContractReport::critical_count

    fn ContractReport::critical_count(self : ContractReport) -> Int

    ContractReport::decision

    fn ContractReport::decision(self : ContractReport) -> String

    ContractReport::is_conformant

    fn ContractReport::is_conformant(self : ContractReport) -> Bool

    ContractReport::json_report

    fn ContractReport::json_report(self : ContractReport) -> String

    ContractReport::parsed

    ContractReport::text_report

    fn ContractReport::text_report(self : ContractReport) -> String

    ContractReport::violation_count

    fn ContractReport::violation_count(self : ContractReport) -> Int

    ContractReport::violations

    ContractReport::warning_count

    fn ContractReport::warning_count(self : ContractReport) -> Int

    ContractViolation

    pub struct ContractViolation {
    kind : ContractViolationKind
    severity : Severity
    key : String
    expected : String
    actual : String
    message : String
    offset : Int
    } derive(Eq,
    Debug
    )

    ContractViolation::actual

    fn ContractViolation::actual(self : ContractViolation) -> String

    ContractViolation::expected

    fn ContractViolation::expected(self : ContractViolation) -> String

    ContractViolation::key

    fn ContractViolation::key(self : ContractViolation) -> String

    ContractViolation::kind

    ContractViolation::message

    fn ContractViolation::message(self : ContractViolation) -> String

    ContractViolation::offset

    fn ContractViolation::offset(self : ContractViolation) -> Int

    ContractViolation::severity

    ContractViolationKind

    pub(all) enum ContractViolationKind {
    ContractSyntaxError
    ContractMissingField
    ContractUnexpectedField
    ContractWrongType
    ContractBlankDisallowed
    ContractFlagDisallowed
    ContractValueTooLong
    ContractValueNotAllowed
    ContractDuplicateField
    ContractFieldLimit
    } derive(Eq,
    Debug
    )

    ContractViolationKind::label

    fn ContractViolationKind::label(self : ContractViolationKind) -> String

    DriftFinding

    pub struct DriftFinding {
    kind : DriftKind
    severity : Severity
    subject : String
    baseline : String
    current : String
    message : String
    } derive(Eq,
    Debug
    )

    DriftFinding::baseline

    fn DriftFinding::baseline(self : DriftFinding) -> String

    DriftFinding::current

    fn DriftFinding::current(self : DriftFinding) -> String

    DriftFinding::kind

    fn DriftFinding::kind(self : DriftFinding) -> DriftKind

    DriftFinding::message

    fn DriftFinding::message(self : DriftFinding) -> String

    DriftFinding::severity

    fn DriftFinding::severity(self : DriftFinding) -> Severity

    DriftFinding::subject

    fn DriftFinding::subject(self : DriftFinding) -> String

    DriftKind

    pub(all) enum DriftKind {
    DriftAddedField
    DriftRemovedField
    DriftTypeChanged
    DriftTypeConfidenceDrop
    DriftPrevalenceIncrease
    DriftPrevalenceDecrease
    DriftValueLengthGrowth
    DriftNewShape
    DriftRetiredShape
    DriftInvalidRateIncrease
    DriftRiskIncrease
    } derive(Eq,
    Debug
    )

    Explainable changes detected between two logfmt batches.

    DriftKind::label

    fn DriftKind::label(self : DriftKind) -> String

    DriftPolicy

    pub struct DriftPolicy {
    prevalence_delta : Int
    confidence_drop : Int
    max_length_growth : Int
    invalid_rate_delta : Int
    average_risk_delta : Int
    min_field_prevalence : Int
    report_retired_shapes : Bool
    } derive(Eq,
    Debug
    )

    DriftPolicy::ci

    DriftPolicy::default

    fn DriftPolicy::default() -> DriftPolicy

    DriftPolicy::exploratory

    fn DriftPolicy::exploratory() -> DriftPolicy

    DriftPolicy::with_invalid_budget

    fn DriftPolicy::with_invalid_budget(self : DriftPolicy, invalid_rate_delta : Int) -> DriftPolicy

    DriftPolicy::with_prevalence_delta

    fn DriftPolicy::with_prevalence_delta(self : DriftPolicy, prevalence_delta : Int) -> DriftPolicy

    DriftPolicy::with_retired_shapes

    fn DriftPolicy::with_retired_shapes(self : DriftPolicy, report_retired_shapes : Bool) -> DriftPolicy

    DriftReport

    pub struct DriftReport {
    baseline_lines : Int
    current_lines : Int
    findings : Array[DriftFinding]
    } derive(Eq,
    Debug
    )

    DriftReport::baseline_lines

    fn DriftReport::baseline_lines(self : DriftReport) -> Int

    DriftReport::critical_count

    fn DriftReport::critical_count(self : DriftReport) -> Int

    DriftReport::current_lines

    fn DriftReport::current_lines(self : DriftReport) -> Int

    DriftReport::decision

    fn DriftReport::decision(self : DriftReport) -> String

    DriftReport::finding_count

    fn DriftReport::finding_count(self : DriftReport) -> Int

    DriftReport::findings

    fn DriftReport::findings(self : DriftReport) -> Array[DriftFinding]

    DriftReport::json_report

    fn DriftReport::json_report(self : DriftReport) -> String

    DriftReport::risk_score

    fn DriftReport::risk_score(self : DriftReport) -> Int

    DriftReport::text_report

    fn DriftReport::text_report(self : DriftReport) -> String

    DriftReport::warning_count

    fn DriftReport::warning_count(self : DriftReport) -> Int

    Field

    pub struct Field {
    key : String
    value : String
    quoted : Bool
    flag : Bool
    offset : Int
    } derive(Eq,
    Debug
    )

    One parsed logfmt field.

    Field::is_flag

    fn Field::is_flag(self : Field) -> Bool

    Field::key

    fn Field::key(self : Field) -> String

    Field::new

    fn Field::new(key : String, value : String, quoted? : Bool, flag? : Bool, offset? : Int) -> Field

    Field::offset

    fn Field::offset(self : Field) -> Int

    Field::pair

    fn Field::pair(self : Field) -> String

    Field::quoted

    fn Field::quoted(self : Field) -> Bool

    Field::value

    fn Field::value(self : Field) -> String

    FieldProfile

    pub struct FieldProfile {
    key : String
    lines_seen : Int
    values_seen : Int
    max_length : Int
    distinct_values : Array[String]
    distribution : ValueDistribution
    } derive(Eq,
    Debug
    )

    FieldProfile::distinct_values

    fn FieldProfile::distinct_values(self : FieldProfile) -> Array[String]

    FieldProfile::distribution

    fn FieldProfile::distribution(self : FieldProfile) -> ValueDistribution

    FieldProfile::dominant_kind

    fn FieldProfile::dominant_kind(self : FieldProfile) -> ValueKind

    FieldProfile::key

    fn FieldProfile::key(self : FieldProfile) -> String

    FieldProfile::lines_seen

    fn FieldProfile::lines_seen(self : FieldProfile) -> Int

    FieldProfile::max_length

    fn FieldProfile::max_length(self : FieldProfile) -> Int

    FieldProfile::prevalence_percent

    fn FieldProfile::prevalence_percent(self : FieldProfile, valid_lines : Int) -> Int

    FieldProfile::summary

    fn FieldProfile::summary(self : FieldProfile, valid_lines : Int) -> String

    FieldProfile::type_confidence

    fn FieldProfile::type_confidence(self : FieldProfile) -> Int

    FieldProfile::values_seen

    fn FieldProfile::values_seen(self : FieldProfile) -> Int

    FieldRule

    pub struct FieldRule {
    key : String
    expected_kind : ValueKind
    required : Bool
    allow_blank : Bool
    allow_flag : Bool
    max_length : Int
    allowed_values : Array[String]
    } derive(Eq,
    Debug
    )

    One executable field rule in a log contract.

    FieldRule::allowed_values

    fn FieldRule::allowed_values(self : FieldRule) -> Array[String]

    FieldRule::allows_blank

    fn FieldRule::allows_blank(self : FieldRule) -> Bool

    FieldRule::allows_flag

    fn FieldRule::allows_flag(self : FieldRule) -> Bool

    FieldRule::describe

    fn FieldRule::describe(self : FieldRule) -> String

    FieldRule::expected_kind

    fn FieldRule::expected_kind(self : FieldRule) -> ValueKind

    FieldRule::key

    fn FieldRule::key(self : FieldRule) -> String

    FieldRule::max_length

    fn FieldRule::max_length(self : FieldRule) -> Int

    FieldRule::required

    fn FieldRule::required(self : FieldRule) -> Bool

    FieldRule::text

    fn FieldRule::text(key : String, required? : Bool) -> FieldRule

    FieldRule::typed

    fn FieldRule::typed(key : String, expected_kind : ValueKind, required? : Bool) -> FieldRule

    FieldRule::with_allowed_values

    fn FieldRule::with_allowed_values(self : FieldRule, allowed_values : Array[String]) -> FieldRule

    FieldRule::with_blank

    fn FieldRule::with_blank(self : FieldRule, allow_blank : Bool) -> FieldRule

    FieldRule::with_flag

    fn FieldRule::with_flag(self : FieldRule, allow_flag : Bool) -> FieldRule

    FieldRule::with_max_length

    fn FieldRule::with_max_length(self : FieldRule, max_length : Int) -> FieldRule

    FieldRule::with_required

    fn FieldRule::with_required(self : FieldRule, required : Bool) -> FieldRule

    Finding

    pub struct Finding {
    kind : FindingKind
    severity : Severity
    key : String
    message : String
    offset : Int
    } derive(Eq,
    Debug
    )

    Finding::key

    fn Finding::key(self : Finding) -> String

    Finding::kind

    fn Finding::kind(self : Finding) -> FindingKind

    Finding::message

    fn Finding::message(self : Finding) -> String

    Finding::new

    fn Finding::new(kind : FindingKind, severity : Severity, key : String, message : String, offset? : Int) -> Finding

    Finding::offset

    fn Finding::offset(self : Finding) -> Int

    Finding::severity

    fn Finding::severity(self : Finding) -> Severity

    FindingKind

    pub(all) enum FindingKind {
    SyntaxError
    DuplicateKey
    RequiredKeyMissing
    TooManyFields
    ValueTooLong
    BlankValue
    FlagField
    ControlCharacter
    } derive(Eq,
    Debug
    )

    Audit finding kinds for logfmt quality and CI review.

    FindingKind::label

    fn FindingKind::label(self : FindingKind) -> String

    InferencePolicy

    pub struct InferencePolicy {
    required_percent : Int
    type_confidence_percent : Int
    enum_cardinality_limit : Int
    unknown_fields : UnknownFieldPolicy
    } derive(Eq,
    Debug
    )

    InferencePolicy::default

    InferencePolicy::enum_cardinality_limit

    fn InferencePolicy::enum_cardinality_limit(self : InferencePolicy) -> Int

    InferencePolicy::exploratory

    fn InferencePolicy::exploratory() -> InferencePolicy

    InferencePolicy::required_percent

    fn InferencePolicy::required_percent(self : InferencePolicy) -> Int

    InferencePolicy::strict

    InferencePolicy::type_confidence_percent

    fn InferencePolicy::type_confidence_percent(self : InferencePolicy) -> Int

    LineReview

    pub struct LineReview {
    line_number : Int
    shape : String
    fingerprint : String
    report : AuditReport
    } derive(
    Debug
    )

    Per-line analysis intentionally omits the original source text.

    LineReview::fingerprint

    fn LineReview::fingerprint(self : LineReview) -> String

    LineReview::is_valid

    fn LineReview::is_valid(self : LineReview) -> Bool

    LineReview::line_number

    fn LineReview::line_number(self : LineReview) -> Int

    LineReview::report

    fn LineReview::report(self : LineReview) -> AuditReport

    LineReview::risk_level

    fn LineReview::risk_level(self : LineReview) -> String

    LineReview::shape

    fn LineReview::shape(self : LineReview) -> String

    LogContract

    pub struct LogContract {
    name : String
    rules : Array[FieldRule]
    unknown_fields : UnknownFieldPolicy
    max_fields : Int
    } derive(
    Debug
    )

    A named, executable schema for logfmt records.

    LogContract::ci_event

    fn LogContract::ci_event() -> LogContract

    A compact contract suited to build and CI logs.

    LogContract::describe

    fn LogContract::describe(self : LogContract) -> String

    LogContract::has_rule

    fn LogContract::has_rule(self : LogContract, key : String) -> Bool

    LogContract::max_fields

    fn LogContract::max_fields(self : LogContract) -> Int

    LogContract::name

    fn LogContract::name(self : LogContract) -> String

    LogContract::new

    fn LogContract::new(name : String, rules : Array[FieldRule], unknown_fields? : UnknownFieldPolicy, max_fields? : Int) -> LogContract

    LogContract::required_count

    fn LogContract::required_count(self : LogContract) -> Int

    LogContract::rule_count

    fn LogContract::rule_count(self : LogContract) -> Int

    LogContract::rules

    fn LogContract::rules(self : LogContract) -> Array[FieldRule]

    LogContract::service

    fn LogContract::service() -> LogContract

    A practical contract for ordinary service logs.

    LogContract::unknown_field_policy

    fn LogContract::unknown_field_policy(self : LogContract) -> UnknownFieldPolicy

    ParseError

    pub struct ParseError {
    kind : ParseErrorKind
    message : String
    offset : Int
    } derive(Eq,
    Debug
    )

    ParseError::kind

    ParseError::message

    fn ParseError::message(self : ParseError) -> String

    ParseError::offset

    fn ParseError::offset(self : ParseError) -> Int

    ParseErrorKind

    pub(all) enum ParseErrorKind {
    EmptyKey
    InvalidKey
    UnexpectedEquals
    UnterminatedQuote
    BareQuote
    } derive(Eq,
    Debug
    )

    Syntax problems found while parsing one logfmt line.

    ParseErrorKind::label

    fn ParseErrorKind::label(self : ParseErrorKind) -> String

    ParseResult

    pub struct ParseResult {
    source : String
    fields : Array[Field]
    errors : Array[ParseError]
    } derive(
    Debug
    )

    ParseResult::error_count

    fn ParseResult::error_count(self : ParseResult) -> Int

    ParseResult::errors

    fn ParseResult::errors(self : ParseResult) -> Array[ParseError]

    ParseResult::field_count

    fn ParseResult::field_count(self : ParseResult) -> Int

    ParseResult::fields

    fn ParseResult::fields(self : ParseResult) -> Array[Field]

    ParseResult::get

    fn ParseResult::get(self : ParseResult, key : String) -> String

    ParseResult::has_key

    fn ParseResult::has_key(self : ParseResult, key : String) -> Bool

    ParseResult::is_valid

    fn ParseResult::is_valid(self : ParseResult) -> Bool

    ParseResult::normalized

    fn ParseResult::normalized(self : ParseResult) -> String

    ParseResult::source

    fn ParseResult::source(self : ParseResult) -> String

    ParseResult::summary

    fn ParseResult::summary(self : ParseResult) -> String

    PrivacyFinding

    pub struct PrivacyFinding {
    key : String
    kind : SensitiveKind
    reason : String
    offset : Int
    } derive(Eq,
    Debug
    )

    PrivacyFinding::key

    fn PrivacyFinding::key(self : PrivacyFinding) -> String

    PrivacyFinding::kind

    PrivacyFinding::offset

    fn PrivacyFinding::offset(self : PrivacyFinding) -> Int

    PrivacyFinding::reason

    fn PrivacyFinding::reason(self : PrivacyFinding) -> String

    PrivacyFinding::severity

    fn PrivacyFinding::severity(self : PrivacyFinding) -> Severity

    RedactionMode

    pub(all) enum RedactionMode {
    RedactFull
    RedactKeepLastFour
    RedactStableToken
    } derive(Eq,
    Debug
    )

    How a sensitive value should be represented in safe output.

    RedactionMode::label

    fn RedactionMode::label(self : RedactionMode) -> String

    RedactionPolicy

    pub struct RedactionPolicy {
    mode : RedactionMode
    secret_key_fragments : Array[String]
    personal_key_fragments : Array[String]
    payment_key_fragments : Array[String]
    network_key_fragments : Array[String]
    allow_keys : Array[String]
    detect_values : Bool
    redact_network_values : Bool
    } derive(
    Debug
    )

    Privacy rules for key-aware and value-aware redaction.

    RedactionPolicy::default

    RedactionPolicy::key_only

    RedactionPolicy::mode

    RedactionPolicy::strict

    RedactionPolicy::with_allow_keys

    fn RedactionPolicy::with_allow_keys(self : RedactionPolicy, allow_keys : Array[String]) -> RedactionPolicy

    RedactionPolicy::with_mode

    RedactionPolicy::with_network_values

    fn RedactionPolicy::with_network_values(self : RedactionPolicy, redact_network_values : Bool) -> RedactionPolicy

    RedactionPolicy::with_value_detection

    fn RedactionPolicy::with_value_detection(self : RedactionPolicy, detect_values : Bool) -> RedactionPolicy

    RedactionResult

    pub struct RedactionResult {
    parsed : ParseResult
    safe_line : String
    findings : Array[PrivacyFinding]
    redacted_keys : Array[String]
    } derive(
    Debug
    )

    The privacy-safe projection of one parsed line.

    Reports never include the original sensitive values. The original source is retained only through the parsed result for in-process callers and is not serialized by the report methods.

    RedactionResult::critical_count

    fn RedactionResult::critical_count(self : RedactionResult) -> Int

    RedactionResult::decision

    fn RedactionResult::decision(self : RedactionResult) -> String

    RedactionResult::finding_count

    fn RedactionResult::finding_count(self : RedactionResult) -> Int

    RedactionResult::findings

    RedactionResult::is_safe

    fn RedactionResult::is_safe(self : RedactionResult) -> Bool

    RedactionResult::json_report

    fn RedactionResult::json_report(self : RedactionResult) -> String

    RedactionResult::parsed

    RedactionResult::redacted_count

    fn RedactionResult::redacted_count(self : RedactionResult) -> Int

    RedactionResult::redacted_keys

    fn RedactionResult::redacted_keys(self : RedactionResult) -> Array[String]

    RedactionResult::safe_line

    fn RedactionResult::safe_line(self : RedactionResult) -> String

    RedactionResult::text_report

    fn RedactionResult::text_report(self : RedactionResult) -> String

    SchemaInference

    pub struct SchemaInference {
    total_lines : Int
    valid_lines : Int
    invalid_lines : Int
    profiles : Array[FieldProfile]
    contract : LogContract
    } derive(
    Debug
    )

    SchemaInference::contract

    SchemaInference::invalid_lines

    fn SchemaInference::invalid_lines(self : SchemaInference) -> Int

    SchemaInference::json_report

    fn SchemaInference::json_report(self : SchemaInference) -> String

    SchemaInference::profile_for

    fn SchemaInference::profile_for(self : SchemaInference, key : String) -> FieldProfile?

    SchemaInference::profiles

    SchemaInference::text_report

    fn SchemaInference::text_report(self : SchemaInference) -> String

    SchemaInference::total_lines

    fn SchemaInference::total_lines(self : SchemaInference) -> Int

    SchemaInference::valid_lines

    fn SchemaInference::valid_lines(self : SchemaInference) -> Int

    SensitiveKind

    pub(all) enum SensitiveKind {
    SensitiveSecret
    SensitiveCredential
    SensitivePersonal
    SensitivePayment
    SensitiveNetwork
    } derive(Eq,
    Debug
    )

    Categories used by the privacy scanner.

    SensitiveKind::label

    fn SensitiveKind::label(self : SensitiveKind) -> String

    SensitiveKind::severity

    fn SensitiveKind::severity(self : SensitiveKind) -> Severity

    Severity

    pub(all) enum Severity {
    Info
    Warning
    Critical
    } derive(Eq,
    Debug
    )

    Severity assigned to an audit finding.

    Severity::label

    fn Severity::label(self : Severity) -> String

    Severity::score

    fn Severity::score(self : Severity) -> Int

    ShapeStat

    pub struct ShapeStat {
    shape : String
    fingerprint : String
    count : Int
    first_line : Int
    } derive(Eq,
    Debug
    )

    A value-free structural cluster. Shape strings contain only field names, semantic kinds, and flag markers.

    ShapeStat::count

    fn ShapeStat::count(self : ShapeStat) -> Int

    ShapeStat::fingerprint

    fn ShapeStat::fingerprint(self : ShapeStat) -> String

    ShapeStat::first_line

    fn ShapeStat::first_line(self : ShapeStat) -> Int

    ShapeStat::shape

    fn ShapeStat::shape(self : ShapeStat) -> String

    ShapeStat::summary

    fn ShapeStat::summary(self : ShapeStat) -> String

    UnknownFieldPolicy

    pub(all) enum UnknownFieldPolicy {
    UnknownAllow
    UnknownWarn
    UnknownReject
    } derive(Eq,
    Debug
    )

    Policy used when a contract encounters a key it does not declare.

    UnknownFieldPolicy::label

    fn UnknownFieldPolicy::label(self : UnknownFieldPolicy) -> String

    ValueDistribution

    pub struct ValueDistribution {
    flag_count : Int
    empty_count : Int
    boolean_count : Int
    integer_count : Int
    decimal_count : Int
    duration_count : Int
    byte_size_count : Int
    timestamp_count : Int
    ipv4_count : Int
    uuid_count : Int
    email_count : Int
    hex_count : Int
    identifier_count : Int
    text_count : Int
    } derive(Eq,
    Debug
    )

    A compact distribution of value kinds.

    ValueDistribution::count

    fn ValueDistribution::count(self : ValueDistribution, kind : ValueKind) -> Int

    ValueDistribution::distinct_kind_count

    fn ValueDistribution::distinct_kind_count(self : ValueDistribution) -> Int

    ValueDistribution::dominant_kind

    fn ValueDistribution::dominant_kind(self : ValueDistribution) -> ValueKind

    ValueDistribution::dominant_percent

    fn ValueDistribution::dominant_percent(self : ValueDistribution) -> Int

    ValueDistribution::empty

    ValueDistribution::summary

    fn ValueDistribution::summary(self : ValueDistribution) -> String

    ValueDistribution::total

    fn ValueDistribution::total(self : ValueDistribution) -> Int

    ValueDistribution::with_kind

    ValueKind

    pub(all) enum ValueKind {
    ValueFlag
    ValueEmpty
    ValueBoolean
    ValueInteger
    ValueDecimal
    ValueDuration
    ValueByteSize
    ValueTimestamp
    ValueIPv4
    ValueUuid
    ValueEmail
    ValueHex
    ValueIdentifier
    ValueText
    } derive(Eq,
    Debug
    )

    Semantic value families recognized by MoonLogfmt Lens.

    The classifier is intentionally deterministic and dependency-free. It does not try to replace a full date, network, or identity parser. Its purpose is to give contract inference and drift analysis a stable vocabulary.

    ValueKind::accepts

    fn ValueKind::accepts(self : ValueKind, actual : ValueKind) -> Bool

    Returns true when values of actual are accepted by a rule for expected.

    Integer values are accepted by decimal rules, while every value can be represented as text. Empty and flag values remain explicit so callers can decide whether they are allowed.

    ValueKind::label

    fn ValueKind::label(self : ValueKind) -> String

    analyze_batch

    fn analyze_batch(lines : Array[String], policy? : BatchPolicy) -> BatchReport

    audit

    fn audit(parsed : ParseResult, policy : AuditPolicy) -> AuditReport

    audit_line

    fn audit_line(line : String) -> AuditReport

    audit_line_with_policy

    fn audit_line_with_policy(line : String, policy : AuditPolicy) -> AuditReport

    classify_field

    fn classify_field(field : Field) -> ValueKind

    Classifies a parsed field while preserving the distinction between an implicit flag and an explicit boolean value.

    classify_value

    fn classify_value(value : String) -> ValueKind

    Classifies one logfmt value using a stable, ordered set of recognizers.

    compare_batches

    fn compare_batches(baseline : BatchReport, current : BatchReport, policy? : DriftPolicy) -> DriftReport

    contract_from_batch

    fn contract_from_batch(report : BatchReport, name? : String, required_percent? : Int, unknown_fields? : UnknownFieldPolicy) -> LogContract

    Freezes a reusable contract from a previously analyzed baseline.

    evaluate_batch

    fn evaluate_batch(report : BatchReport, policy? : BatchGatePolicy) -> BatchDecision

    infer_schema

    fn infer_schema(lines : Array[String], policy? : InferencePolicy) -> SchemaInference

    is_valid

    fn is_valid(line : String) -> Bool

    parse

    fn parse(line : String) -> ParseResult

    profile_values

    fn profile_values(values : Array[String]) -> ValueDistribution

    redact_line

    fn redact_line(line : String, policy? : RedactionPolicy) -> RedactionResult

    redact_parsed

    fn redact_parsed(parsed : ParseResult, policy : RedactionPolicy) -> RedactionResult

    scan_privacy

    fn scan_privacy(line : String) -> RedactionResult

    Scans without changing policy defaults. The returned safe line can be used directly in diagnostics, fixtures, or support bundles.

    shape_fingerprint

    fn shape_fingerprint(shape : String) -> String

    Stable, non-cryptographic identifier for a value-free structural shape.

    structural_shape

    fn structural_shape(parsed : ParseResult) -> String

    Returns a canonical shape independent of field order and field values.

    structural_template

    fn structural_template(line : String) -> String

    Returns a value-free template in original field order.

    validate_contract

    fn validate_contract(line : String, contract : LogContract) -> ContractReport

    validate_parsed_contract

    fn validate_parsed_contract(parsed : ParseResult, contract : LogContract) -> ContractReport