> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ankra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Log Sources

> Connect Grafana Loki, Elasticsearch or OpenSearch so Ankra can search historical logs and power log-aware AI troubleshooting

<Note>
  Log sources let Ankra query your aggregated log store through the cluster agent. This powers the **Search** tab on the cluster Logs page and the AI Assistant's `query_logs` / `get_log_labels` tools.
</Note>

## Why Connect a Log Source?

When you connect a log source to Ankra:

* **Historical log search** - Query logs across pods and namespaces without leaving the cluster view
* **AI-powered troubleshooting** - Ankra AI can search Loki, Elasticsearch or OpenSearch during incident analysis
* **Complements live streaming** - Use **Live stream** for tailing current pod output; use **Search** for time-ranged queries over your log store
* **Agent-mediated access** - Queries run from inside your cluster, so in-cluster Loki/Elastic endpoints and external SaaS endpoints both work when the agent can reach them

***

## Supported Providers

| Provider      | Typical in-cluster endpoint              | Auth                                                                         |
| ------------- | ---------------------------------------- | ---------------------------------------------------------------------------- |
| Grafana Loki  | `http://loki-gateway.monitoring.svc:80`  | Bearer token; optional `X-Scope-OrgID` for multi-tenant Loki / Grafana Cloud |
| Elasticsearch | `https://elasticsearch.logging.svc:9200` | API key (recommended) or basic auth                                          |
| OpenSearch    | `https://opensearch.logging.svc:9200`    | Bearer token or basic auth                                                   |

<Warning>
  Use **index-scoped** credentials for Elasticsearch/OpenSearch. Ankra health checks call `{index}/_count`, not `/_cluster/health`, so least-privilege API keys work without false "degraded" status.
</Warning>

***

## Connecting a Log Source

<Steps>
  <Step title="Open Data Sources">
    Navigate to your cluster → **Settings** → **Data Sources**.
  </Step>

  <Step title="Select Log Source">
    Choose **Log Source** in the sidebar (requires the `log_source` feature flag for your organisation).
  </Step>

  <Step title="Pick a provider">
    Select **Grafana Loki**, **Elasticsearch**, or **OpenSearch**.
  </Step>

  <Step title="Enter the endpoint">
    Provide the HTTP endpoint reachable from the Ankra agent inside the cluster.

    Examples:

    ```
    http://loki-gateway.monitoring.svc:80
    https://elasticsearch.logging.svc:9200
    ```

    For Grafana Cloud Loki, use the tenant query URL from your Grafana Cloud stack.
  </Step>

  <Step title="Configure provider options">
    * **Loki** - Optional tenant ID (`X-Scope-OrgID`) for multi-tenant deployments
    * **Elasticsearch / OpenSearch** - Index pattern (default `*`) and optional field mappings if your shipper uses non-standard field names
    * **Verify TLS certificate** - Enable when the endpoint presents a publicly trusted or cluster-trusted certificate; leave off for self-signed in-cluster endpoints
  </Step>

  <Step title="Add credentials (if required)">
    Choose the auth type that matches your deployment:

    * **API Token** - Bearer token (Loki, OpenSearch, Grafana Cloud)
    * **API Key** - Elasticsearch `Authorization: ApiKey …` header
    * **User Account** - HTTP basic auth
  </Step>

  <Step title="Test and save">
    Click **Test connection**, then **Save**. The sidebar status dot turns green when the background health probe succeeds.
  </Step>
</Steps>

***

## Field mappings (Elasticsearch / OpenSearch)

If you ship logs with Fluent Bit's kubernetes filter, the defaults usually work:

| Logical field | Default path                |
| ------------- | --------------------------- |
| Timestamp     | `@timestamp`                |
| Message       | `message`                   |
| Namespace     | `kubernetes.namespace_name` |
| Pod           | `kubernetes.pod_name`       |
| Container     | `kubernetes.container_name` |

Override these in the **Advanced field mappings** section when your index template uses different names.

For **Loki**, structured filters use label names (defaults: `namespace`, `pod`, `container` for Promtail/Alloy).

***

## Searching logs in the portal

1. Open **Logs** in the cluster sidebar
2. Switch to the **Search** tab (visible when the log source feature is enabled)
3. Pick a time range and optional namespace/pod/container filters
4. Enter a text search or toggle **Raw query** for LogQL (Loki) or JSON query-DSL (Elasticsearch/OpenSearch)
5. Use **Load older** to page backward in time

From a pod's **Logs** tab, **Search history** deep-links into Search with that pod pre-filtered.

***

## AI Assistant

With a configured log source, Ankra AI can:

* `query_logs` - Run structured or raw queries over the connected store
* `get_log_labels` - Discover filterable labels/fields before querying

The assistant uses the same agent relay as the portal - credentials never leave the platform vault.

<Tip>
  Ask Ankra AI to call `get_log_labels` first when filters return no rows; your shipper may use different label or field names than the defaults.
</Tip>

***

## Troubleshooting

| Symptom                     | Likely cause                                                                                          |
| --------------------------- | ----------------------------------------------------------------------------------------------------- |
| Status dot grey             | No log source saved yet                                                                               |
| Status dot amber (degraded) | Credential rejected (401/403) or probe returned an error                                              |
| Search says cluster offline | Agent not connected - live pod logs will also fail                                                    |
| Query timeout               | Narrow the time range or add namespace/pod filters                                                    |
| Empty search results        | Wrong index pattern or field mappings; try `get_log_labels` via AI or verify labels in Grafana/Kibana |
