Hikari Documentation

Installation

Deploy Hikari

Hikari runs as a Python/FastAPI service with a built web UI. Use the mock VictoriaLogs backend for local development, or point the service at your own VictoriaLogs deployment.

Local development

Copy the example environment and start the mock backend, API, and Vite UI.

Copy-Item .env.example .env
docker compose up mock-victorialogs api web
ServiceURL
webhttp://localhost:5173
apihttp://localhost:8000
mock-victorialogshttp://localhost:9428

To run the production-style combined image locally:

docker compose up hikari

Prebuilt container image

The OSS repository publishes a multi-architecture image to GitHub Container Registry.

ghcr.io/bradmb/hikari:latest

latest follows main. Version tags are published from Git tags that match v*.*.*, and each build also gets a sha-... tag. For production, pin a version tag or SHA tag instead of latest.

docker run --rm -p 8000:8000 `
  -e HIKARI_VICTORIA_URL=https://victorialogs.example.com `
  ghcr.io/bradmb/hikari:latest

Configuration

VariableDescription
HIKARI_VICTORIA_URLVictoriaLogs base URL.
HIKARI_VICTORIA_BEARER_TOKENOptional bearer token for VictoriaLogs.
HIKARI_VICTORIA_HEADERSOptional JSON object of extra headers for VictoriaLogs.
HIKARI_FIELD_MAPPINGS_FILEJSON file that defines canonical fields, facet aliases, and sidebar facets.
HIKARI_FIELD_MAPPINGSOptional inline JSON override for field mappings.
HIKARI_DEFAULT_PAGESets startup route for /. Use browse (default) or ai.
HIKARI_FACET_PREVIEW_LIMITNumber of values shown per facet before the View more expander appears. Defaults to 10.
OPENAI_API_KEYOptional key for natural-language query generation. Inject this directly from your platform's secret mechanism.
HIKARI_OPENAI_API_KEY_SECRET_IDOptional AWS Secrets Manager secret ID for AWS deployments that load the OpenAI key at runtime.
HIKARI_OPENAI_MODELModel used for natural-language query generation.

By default, HIKARI_DEFAULT_PAGE is browse, so the root path routes to /browse. Set it to ai to route / to /ai.

Facet mapping

Hikari adapts to your log schema through config/field-mappings.json. This file controls display fields, sidebar facets, MCP summary facets, and hidden query normalization.

Set HIKARI_FACET_PREVIEW_LIMIT to control how many values each facet shows before the UI displays a View more expander. The default is 10.

Use aliases to map source fields into canonical Hikari facets. For example, Windows or OpenTelemetry logs can populate service and host from alternate field names:

{
  "aliases": {
    "service": ["service", "service.name", "service_name", "kubernetes.container_name"],
    "host": ["host", "host.name", "host_name", "hostname", "kubernetes.pod_node_name"]
  }
}

Hikari applies these mappings to backend VictoriaLogs requests with hidden LogsQL copy pipes. Users still see clean queries like _time:15m service:="api", while Hikari sends generated copies such as copy service_name as service and copy host_name as host before loading rows, facets, field values, hit buckets, live tail data, AI context, and MCP results.

Hikari expects canonical facet values to exist as stored VictoriaLogs fields. For severity, Hikari maps structured fields such as severity_text, SeverityText, and OpenTelemetry severity_number into the canonical level field. It can also append configurable VictoriaLogs unpack_json and extract_regexp pipes for common message-only level formats. The OSS mapping sets severity.defaultMissing to info, so rows with no severity signal are normalized at query/display time, not rewritten at ingestion. Prefer ingestion-time normalization for high-volume streams and very large deployments.

Use facets to choose the canonical groups shown in the sidebar and MCP summaries.

{
  "facets": [
    { "field": "environment", "label": "Environment" },
    { "field": "service", "label": "Service", "summary": true },
    { "field": "host", "label": "Host", "summary": true },
    { "field": "level", "label": "Level", "summary": true },
    { "field": "kubernetes.pod_namespace", "key": "namespace", "label": "Namespace", "summary": true },
    { "field": "kubernetes.pod_name", "key": "pod", "label": "Pod", "summary": true }
  ]
}

The optional key gives MCP summaries a shorter name. Set summary: true for facets that should appear in summarize_window and default get_facets output.

Configure facets with Helm

The Helm chart creates a ConfigMap from fieldMappings.config and mounts it at /app/config/field-mappings.json. The chart also sets HIKARI_FIELD_MAPPINGS_FILE to that path.

fieldMappings:
  enabled: true
  config:
    defaultFields:
      - environment
      - service
      - service_name
      - host
      - host_name
      - level
      - kubernetes.pod_namespace
      - kubernetes.pod_name
    aliases:
      service:
        - service
        - service.name
        - service_name
        - kubernetes.container_name
      host:
        - host
        - host.name
        - host_name
        - hostname
        - kubernetes.pod_node_name
      level:
        - level
        - severity_text
        - SeverityText
        - severity
        - Severity
        - severity_number
        - SeverityNumber
    severity:
      canonicalField: level
      defaultMissing: info
      textFields:
        - level
        - severity_text
        - SeverityText
        - severity
        - Severity
      numberFields:
        - severity_number
        - SeverityNumber
      values:
        error: [error, err, fatal, critical, crit, alert, emerg, e, f]
        warning: [warning, warn, notice, w]
        info: [info, information, informational, i]
        debug: [debug, trace, verbose]
      messageFilters:
        error:
          - _msg:~'"level"[[:space:]]*:[[:space:]]*"(error|err|fatal|critical|crit|alert|emerg)'
          - _msg:~'[[](emerg|alert|crit|critical|error|err)[]]'
          - _msg:~'^E[0-9]{4}'
          - _msg:~'^F[0-9]{4}'
        warning:
          - _msg:~'"level"[[:space:]]*:[[:space:]]*"(warn|warning|notice)'
          - _msg:~'[[](warn|warning|notice)[]]'
          - _msg:~'^W[0-9]{4}'
        info:
          - _msg:~'"level"[[:space:]]*:[[:space:]]*"(info|information|informational)'
          - _msg:~'^I[0-9]{4}'
        debug:
          - _msg:~'"level"[[:space:]]*:[[:space:]]*debug'
      numberRanges:
        debug: [1, 8]
        info: [9, 12]
        warning: [13, 16]
        error: [17, 24]
      extractPipes:
        - unpack_json fields (level,severity,severity_text,severity_number,msg,message) keep_original_fields
        - extract_regexp '^(?P<level>[IWEF])[0-9]{4}[[:space:]]' from _msg keep_original_fields
        - extract_regexp '^(?P<level>INFO|WARN|WARNING|ERROR|ERR|DEBUG|TRACE|VERBOSE|FATAL|CRITICAL|emerg|alert|crit|critical|error|err|warn|warning|notice|info|debug|trace|verbose|fatal)[[:space:]:]' from _msg keep_original_fields
        - extract_regexp '[[](?P<level>emerg|alert|crit|critical|error|err|warn|warning|notice|info|debug|trace)[]]' from _msg keep_original_fields
    facets:
      - field: environment
        label: Environment
      - field: service
        label: Service
        summary: true
      - field: host
        label: Host
        summary: true
      - field: level
        label: Level
        summary: true
      - field: kubernetes.pod_namespace
        key: namespace
        label: Namespace
        summary: true
      - field: kubernetes.pod_name
        key: pod
        label: Pod
        summary: true
helm upgrade --install hikari ./k8s/helm/hikari `
  --namespace hikari `
  --create-namespace `
  --values ./hikari-values.yaml `
  --set image.repository=ghcr.io/bradmb/hikari `
  --set-string image.tag=latest `
  --set env.facetPreviewLimit=10 `
  --set env.victoriaUrl=http://victorialogs.example.svc:9428

Why am I not seeing levels?

Hikari reads level as its canonical severity field. It can map structured source fields like severity_text and severity_number, and it can run configured VictoriaLogs extraction pipes for common _msg formats. If severity.defaultMissing is set, rows with no severity signal use that canonical level at query/display time. If rows show unknown or appear to have the wrong level, first inspect the fields stored in VictoriaLogs and the mapping file mounted into Hikari.

_time:15m | limit 1
_time:15m level:*
_time:15m severity_text:*
_time:15m severity_number:*

If the level only appears inside _msg or another message payload, add a matching severity.extractPipes entry or update the collector/application logger to emit a structured severity field before ingestion. For Kubernetes collectors, check the Fluent Bit ConfigMaps and restart the DaemonSet after changing normalization.

kubectl -n victorialogs get configmap victorialogs-collector-fluent-bit -o yaml
kubectl -n victorialogs get configmap fluentbit-lua-scripts -o yaml
kubectl -n victorialogs rollout restart daemonset/victorialogs-collector-fluent-bit
kubectl -n victorialogs rollout status daemonset/victorialogs-collector-fluent-bit

Kubernetes

Install the included Helm chart with the GHCR image or your own image registry.

helm upgrade --install hikari ./k8s/helm/hikari `
  --namespace hikari `
  --create-namespace `
  --set image.repository=ghcr.io/bradmb/hikari `
  --set-string image.tag=latest `
  --set env.victoriaUrl=http://victorialogs.example.svc:9428

Optional AI search only needs OPENAI_API_KEY. In Kubernetes, inject it from a Kubernetes Secret or your platform's native secret mechanism. AWS Secrets Manager is supported as an opt-in integration, but it is not required.

helm upgrade --install hikari ./k8s/helm/hikari `
  --namespace hikari `
  --set env.openAiSecretName=hikari-openai `
  --set env.openAiSecretKey=OPENAI_API_KEY

Verify the rollout and health endpoint.

kubectl -n hikari rollout status deployment/hikari
kubectl -n hikari port-forward deployment/hikari 8000:8000

curl http://localhost:8000/health

Bring your own authentication

Hikari does not include end-user authentication or authorization. The safest deployment is to keep it off the public Internet and expose it only on an internal network.

If you need external access, put the UI, API, and MCP endpoint behind your own access layer. Common options include Cloudflare Access, Tailscale, WireGuard, Teleport, OAuth2 Proxy, Pomerium, an SSO-aware reverse proxy, or a cloud provider private application gateway.

Protect MCP access the same way you protect the UI. MCP tools can query logs, discover fields, and return operational data.

Deployment targets

Hikari is a Python/FastAPI application packaged as a container. Deploy it on a container platform, VM, or Kubernetes cluster.

Troubleshooting

  • Check /health to confirm the active VictoriaLogs URL and default query.
  • Confirm the API container or pod can reach HIKARI_VICTORIA_URL.
  • If a host or service is missing from facets, add its source field to aliases in the field mapping config.
  • For MCP capability failures, use HTTP transport and /mcp.
  • AI features are hidden unless OPENAI_API_KEY is configured, or the optional AWS Secrets Manager ID resolves to a key.