# Visibility and Logs

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/management/core/visibility>.

As a zero trust architecture, one of the main goals of Octelium's architecture and its reliance on identity-aware proxies is to provide clear, structured, identity-based, application-layer aware visibility and auditing. Octelium is built to be [OpenTelemetry](https://opentelemetry.io/)-native and emits all logs and metrics in real-time, which not only clearly identify the subject (i.e. the *User*, their *Session* and *Device* if available) and the resource represented by the *Service* and its *Namespace*, but can also provide you with application-layer specific details of the request (e.g. paths, methods, user agent, query parameters, and even optionally body content in the case of HTTP-based *Services*, database queries in the case of PostgreSQL and MySQL-based *Services*, session recording in the case of SSH-based *Services*, DNS queries and answers in the case of DNS-based *Services*, etc...).

*Diagram: Visibility.* [View the diagram on the canonical HTML page](https://octelium.com/docs/octelium/latest/management/core/visibility).

## OpenTelemetry

All logs and metrics produced by the different Octelium components including *Services* are compatible with [OpenTelemetry](https://opentelemetry.io/). OpenTelemetry is a modern framework that is designed to standardize observability including logs, metrics, and traces. Each *Service*, or more specifically, the identity-aware proxy (IaP) component that implements the *Service*, [*Vigil*](https://octelium.com/docs/octelium/latest/reference/components.md#vigil), emits its access logs in real time to an OpenTelemetry Protocol (OTLP) gRPC receiver that must be listening on the address `octelium-collector.octelium.svc:8080` (i.e. the receiver must be deployed as a Kubernetes service with the name `octelium-collector` in the Kubernetes namespace `octelium`). While you can write and deploy your own custom OTLP receiver fairly easily, it is much simpler for most use cases to simply deploy the official OTLP collector (read more [here](https://opentelemetry.io/docs/collector/)) inside the Kubernetes cluster as a Kubernetes service. You can also use the [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib) as it already includes many exporters to various major log management and SIEM vendors. And you can also use the official OpenTelemetry Helm chart as shown [here](https://opentelemetry.io/docs/platforms/kubernetes/helm/collector/).

> **Note:**
>
> Octelium provides a commercial, scalable OpenTelemetry collector that integrates with Grafana, Splunk, Elastic, Logz.io as well as any OTLP and OTLP-HTTP based providers on demand. You can see the list of our offerings [here](https://octelium.com/enterprise).

This is an example on how to deploy the contrib OTEL collector via Helm to show all the *Cluster* logs and metrics to the collector pod stdout via a `debug` exporter:

```bash
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update


helm install my-otel open-telemetry/opentelemetry-collector -n octelium -f - <<EOF
mode: deployment
image:
  repository: "otel/opentelemetry-collector-contrib"
podLabels:
  octelium.com/component: "collector"
ports:
  otlp:
    enabled: true
    containerPort: 4317
    servicePort: 8080
    hostPort: 4317
    protocol: TCP
    appProtocol: grpc

fullnameOverride: octelium-collector

config:
  exporters:
    debug:
      verbosity: normal
  processors:
    batch: {}
    memory_limiter:
      check_interval: 2s
      limit_percentage: 80
      spike_limit_percentage: 25
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317
        http:
          endpoint: 0.0.0.0:4318
  service:
    pipelines:
      logs:
        exporters:
          - debug
        processors:
          - memory_limiter
          - batch
        receivers:
          - otlp
      metrics:
        exporters:
          - debug
        processors:
          - memory_limiter
          - batch
        receivers:
          - otlp
      traces:
        exporters:
          - debug
        processors:
          - memory_limiter
          - batch
        receivers:
          - otlp
EOF
```

## Logs

### AccessLog

Octelium provides a unified `AccessLog` structure for access logs. Here is an example of a JSON representation of an HTTP request (i.e. the *Service* is using the `HTTP` mode).

```json
{
  "apiVersion": "core/v1",
  "kind": "AccessLog",
  "metadata": {
    "id": "ay54-axtr-fluefgxe5gmo6n051swb18sz-7btn-71r5",
    "createdAt": "2025-09-10T22:03:52.866580252Z",
    "actorRef": {
      "apiVersion": "core/v1",
      "kind": "Session",
      "uid": "5da80a64-a876-4927-a360-09c70e8ac7ff",
      "name": "usr1-rqgw1a",
      "resourceVersion": "019935a6-325c-770d-b6d0-4e12c9bf987f"
    },
    "targetRef": {
      "apiVersion": "core/v1",
      "kind": "Service",
      "uid": "767905b7-6354-4331-aa64-c375379853bc",
      "name": "nginx.default",
      "resourceVersion": "019934cf-4030-7122-b521-87590c462553"
    }
  },
  "entry": {
    "common": {
      "startedAt": "2025-09-10T22:02:49.760632610Z",
      "endedAt": "2025-09-10T22:03:52.866582692Z",
      "status": "ALLOWED",
      "mode": "WEB",
      "reason": {
        "type": "POLICY_MATCH",
        "details": {
          "policyMatch": {
            "inlinePolicy": {
              "resourceRef": {
                "apiVersion": "core/v1",
                "kind": "Group",
                "uid": "b0fc2727-4522-47e5-acf7-97950913e5c9",
                "name": "g1",
                "resourceVersion": "019934cf-33ec-72c1-8314-92b91fae5db6"
              },
              "name": "allow-all"
            }
          }
        }
      },
      "sessionRef": {
        "apiVersion": "core/v1",
        "kind": "Session",
        "uid": "5da80a64-a876-4927-a360-09c70e8ac7ff",
        "name": "usr1-rqgw1a",
        "resourceVersion": "019935a6-325c-770d-b6d0-4e12c9bf987f"
      },
      "userRef": {
        "apiVersion": "core/v1",
        "kind": "User",
        "uid": "a9a47e77-93dc-4285-876a-632cb2b43094",
        "name": "usr1",
        "resourceVersion": "019934cf-3510-7b59-ac80-7a42815cdadd"
      },
      "serviceRef": {
        "apiVersion": "core/v1",
        "kind": "Service",
        "uid": "767905b7-6354-4331-aa64-c375379853bc",
        "name": "nginx.default",
        "resourceVersion": "019934cf-4030-7122-b521-87590c462553"
      },
      "namespaceRef": {
        "apiVersion": "core/v1",
        "kind": "Namespace",
        "uid": "2073e6f7-24c2-49d2-b0df-e5cd3636d82c",
        "name": "default",
        "resourceVersion": "019934c7-6d7a-73cd-a510-dfadfdfa6682"
      },
      "regionRef": {
        "apiVersion": "core/v1",
        "kind": "Region",
        "uid": "85477de2-67d3-48ed-bda7-6c914489badf",
        "name": "default"
      },
      "isPublic": true
    },
    "info": {
      "http": {
        "request": {
          "path": "/",
          "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
          "method": "GET",
          "uri": "/?arg=value"
        },
        "response": {
          "code": 200,
          "bodyBytes": "615",
          "body": "PCFET0NUWVB...",
          "contentType": "text/html"
        },
        "httpVersion": "HTTP11"
      }
    }
  }
}
```

You can discover more about the *AccessLog* layer-7 specific information for the following modes:

- [HTTP](https://octelium.com/docs/octelium/latest/management/core/service/http.md#visibility)
- [SSH](https://octelium.com/docs/octelium/latest/management/core/service/ssh.md#visibility)
- [Kubernetes](https://octelium.com/docs/octelium/latest/management/core/service/kubernetes.md#visibility)
- [PostgreSQL](https://octelium.com/docs/octelium/latest/management/core/service/postgres.md#visibility)
- [MySQL](https://octelium.com/docs/octelium/latest/management/core/service/mysql.md#visibility)
- [TCP](https://octelium.com/docs/octelium/latest/management/core/service/tcp.md#visibility)
- [UDP](https://octelium.com/docs/octelium/latest/management/core/service/udp.md#visibility)
- [gRPC](https://octelium.com/docs/octelium/latest/management/core/service/http.md#grpc-mode)
- [DNS](https://octelium.com/docs/octelium/latest/management/core/service/dns.md#visibility)
- [LLM](https://octelium.com/docs/octelium/latest/management/core/service/llm/visibility.md)
- [MCP](https://octelium.com/docs/octelium/latest/management/core/service/mcp/visibility.md)

[AccessLog JSON Schema (Octelium core/v1, latest documentation)](https://octelium.com/schemas/octelium/latest/AccessLog.schema.json)

### ComponentLog

Octelium also provides a unified `ComponentLog` structure for logs produced by the different Octelium components such as [*Nocturne*](https://octelium.com/docs/octelium/latest/reference/components.md#nocturne) and [*Vigil*](https://octelium.com/docs/octelium/latest/reference/components.md#vigil).

[ComponentLog JSON Schema (Octelium core/v1, latest documentation)](https://octelium.com/schemas/octelium/latest/ComponentLog.schema.json)
