<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Send log data to Loki on Grafana Labs</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/</link><description>Recent content in Send log data to Loki on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/loki/v3.7.x/send-data/index.xml" rel="self" type="application/rss+xml"/><item><title>Ingesting logs to Loki using Alloy</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/alloy/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/alloy/</guid><content><![CDATA[&lt;h1 id=&#34;ingesting-logs-to-loki-using-alloy&#34;&gt;Ingesting logs to Loki using Alloy&lt;/h1&gt;
&lt;p&gt;Grafana Alloy is a versatile observability collector that can ingest logs in various formats and send them to Loki. We recommend Alloy as the primary method for sending logs to Loki, as it provides a more robust and feature-rich solution for building a highly scalable and reliable observability pipeline.&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 1277px;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link&#34;
        href=&#34;/media/docs/alloy/flow-diagram-small-alloy.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload &#34;
          data-src=&#34;/media/docs/alloy/flow-diagram-small-alloy.png&#34;data-srcset=&#34;/media/docs/alloy/flow-diagram-small-alloy.png?w=320 320w, /media/docs/alloy/flow-diagram-small-alloy.png?w=550 550w, /media/docs/alloy/flow-diagram-small-alloy.png?w=750 750w, /media/docs/alloy/flow-diagram-small-alloy.png?w=900 900w, /media/docs/alloy/flow-diagram-small-alloy.png?w=1040 1040w, /media/docs/alloy/flow-diagram-small-alloy.png?w=1240 1240w, /media/docs/alloy/flow-diagram-small-alloy.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;Alloy flow diagram&#34;width=&#34;1277&#34;height=&#34;454&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;/media/docs/alloy/flow-diagram-small-alloy.png&#34;
            alt=&#34;Alloy flow diagram&#34;width=&#34;1277&#34;height=&#34;454&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;h2 id=&#34;installing-alloy&#34;&gt;Installing Alloy&lt;/h2&gt;
&lt;p&gt;To get started with Grafana Alloy and send logs to Loki, you need to install and configure Alloy. You can follow the &lt;a href=&#34;/docs/alloy/latest/get-started/install/&#34;&gt;Alloy documentation&lt;/a&gt; to install Alloy on your preferred platform.&lt;/p&gt;
&lt;h2 id=&#34;components-of-alloy-for-logs&#34;&gt;Components of Alloy for logs&lt;/h2&gt;
&lt;p&gt;Alloy pipelines are built using components that perform specific functions. For logs these can be broken down into three categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Collector:&lt;/strong&gt; These components collect/receive logs from various sources. This can be scraping logs from a file, receiving logs over HTTP, gRPC or ingesting logs from a message queue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transformer:&lt;/strong&gt; These components can be used to manipulate logs before they are sent to a writer. This can be used to add additional metadata, filter logs, or batch logs before sending them to a writer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Writer:&lt;/strong&gt; These components send logs to the desired destination. Our documentation will focus on sending logs to Loki, but Alloy supports sending logs to various destinations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;log-components-in-alloy&#34;&gt;Log components in Alloy&lt;/h3&gt;
&lt;p&gt;Here is a non-exhaustive list of components that can be used to build a log pipeline in Alloy. For a complete list of components, refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/&#34;&gt;components list&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Component&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.api/&#34;&gt;loki.source.api&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.awsfirehose/&#34;&gt;loki.source.awsfirehose&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.azure_event_hubs/&#34;&gt;loki.source.azure_event_hubs&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.cloudflare/&#34;&gt;loki.source.cloudflare&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.docker/&#34;&gt;loki.source.docker&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.file/&#34;&gt;loki.source.file&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.gcplog/&#34;&gt;loki.source.gcplog&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.gelf/&#34;&gt;loki.source.gelf&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.heroku/&#34;&gt;loki.source.heroku&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.journal/&#34;&gt;loki.source.journal&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.kafka/&#34;&gt;loki.source.kafka&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.kubernetes/&#34;&gt;loki.source.kubernetes&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.kubernetes_events/&#34;&gt;loki.source.kubernetes_events&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.podlogs/&#34;&gt;loki.source.podlogs&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.syslog/&#34;&gt;loki.source.syslog&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.source.windowsevent/&#34;&gt;loki.source.windowsevent&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Collector&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.receiver.loki/&#34;&gt;otelcol.receiver.loki&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Transformer&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.relabel/&#34;&gt;loki.relabel&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Transformer&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.process/&#34;&gt;loki.process&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Writer&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/loki.write/&#34;&gt;loki.write&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Writer&lt;/td&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.exporter.loki/&#34;&gt;otelcol.exporter.loki&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;learning-path&#34;&gt;Learning path&lt;/h2&gt;

&lt;Box backgroundColor=&#34;primary&#34; borderColor=&#34;strong&#34; borderStyle=&#34;solid&#34; padding=&#34;2&#34;&gt;
  &lt;Grid columns=&#34;2&#34; gap=&#34;2&#34;&gt;
    &lt;div&gt;
      &lt;h4&gt;Start your learning experience with Grafana Learning Paths&lt;/h4&gt;
      &lt;p&gt;Grafana Learning Paths provide a clear, structured path that leads you from beginner concepts to advanced use cases. Learn about this Grafana feature on &lt;a href=&#34;/docs/learning-paths/send-logs-alloy-loki/&#34;&gt;Send logs to Grafana Cloud using Alloy&lt;/a&gt;.&lt;/p&gt;
      &lt;div&gt;
        &lt;a class=&#34;btn btn--primary arrow&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; href=&#34;https://grafana.com/docs/learning-paths/send-logs-alloy-loki/&#34;&gt;Start learning&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;img src=&#34;/media/docs/learning-journey/map.svg&#34; width=&#34;228&#34; height=&#34;182&#34; alt=&#34;Start your learning experience with Grafana Learning Paths&#34;&gt;
    &lt;/div&gt;
  &lt;/Grid&gt;
&lt;/Box&gt;

&lt;h2 id=&#34;interactive-tutorials&#34;&gt;Interactive Tutorials&lt;/h2&gt;
&lt;p&gt;To learn more about how to configure Alloy to send logs to Loki within different scenarios, follow these interactive tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;examples/alloy-otel-logs/&#34;&gt;Sending OpenTelemetry logs to Loki using Alloy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;examples/alloy-kafka-logs/&#34;&gt;Sending logs over Kafka to Loki using Alloy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="ingesting-logs-to-loki-using-alloy">Ingesting logs to Loki using Alloy&lt;/h1>
&lt;p>Grafana Alloy is a versatile observability collector that can ingest logs in various formats and send them to Loki. We recommend Alloy as the primary method for sending logs to Loki, as it provides a more robust and feature-rich solution for building a highly scalable and reliable observability pipeline.&lt;/p></description></item><item><title>Ingesting logs to Loki using OpenTelemetry Collector</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/otel/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/otel/</guid><content><![CDATA[&lt;h1 id=&#34;ingesting-logs-to-loki-using-opentelemetry-collector&#34;&gt;Ingesting logs to Loki using OpenTelemetry Collector&lt;/h1&gt;


&lt;div data-shared=&#34;otel.md&#34;&gt;
            &lt;p&gt;Loki natively supports ingesting OpenTelemetry logs over HTTP.
For ingesting logs to Loki using the OpenTelemetry Collector, you must use the &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;otlphttp&lt;/code&gt; exporter&lt;/a&gt;.&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#39;https://www.youtube.com/embed/snXhe1fDDa8&#39; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;For more information about using OpenTelemetry with Grafana products, refer to the &lt;a href=&#34;/docs/opentelemetry/&#34;&gt;Grafana OpenTelemetry documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;loki-configuration&#34;&gt;Loki configuration&lt;/h2&gt;
&lt;p&gt;When logs are ingested by Loki using an OpenTelemetry protocol (OTLP) ingestion endpoint, some of the data is stored as &lt;a href=&#34;../../get-started/labels/structured-metadata/&#34;&gt;Structured Metadata&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You must set &lt;code&gt;allow_structured_metadata&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; within your Loki config file. Otherwise, Loki will reject the log payload as malformed.  Note that Structured Metadata is enabled by default in Loki 3.0 and later.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;limits_config:
  allow_structured_metadata: true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;configure-the-opentelemetry-collector-to-write-logs-into-loki&#34;&gt;Configure the OpenTelemetry Collector to write logs into Loki&lt;/h2&gt;
&lt;p&gt;You need to make the following changes to the &lt;a href=&#34;https://opentelemetry.io/docs/collector/configuration/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry Collector config&lt;/a&gt; to write logs to Loki on its OTLP ingestion endpoint.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;exporters:
  otlphttp:
    endpoint: http://&amp;lt;loki-addr&amp;gt;/otlp&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And enable it in &lt;code&gt;service.pipelines&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;service:
  pipelines:
    logs:
      receivers: [...]
      processors: [...]
      exporters: [..., otlphttp]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you want to authenticate using basic auth, we recommend the &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;basicauth&lt;/code&gt; extension&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;extensions:
  basicauth/otlp:
    client_auth:
      username: username
      password: password

exporters:
  otlphttp:
    auth:
      authenticator: basicauth/otlp
    endpoint: http://&amp;lt;loki-addr&amp;gt;/otlp

service:
  extensions: [basicauth/otlp]
  pipelines:
    logs:
      receivers: [...]
      processors: [...]
      exporters: [..., otlphttp]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;format-considerations&#34;&gt;Format considerations&lt;/h2&gt;
&lt;p&gt;Since the OpenTelemetry protocol differs from the Loki storage model, here is how data in the OpenTelemetry format will be mapped by default to the Loki data model during ingestion, which can be changed as explained later:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Index labels: Resource attributes map well to index labels in Loki, since both usually identify the source of the logs. The default list of Resource Attributes to store as Index labels can be configured using &lt;code&gt;default_resource_attributes_as_index_labels&lt;/code&gt; under 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/#distributor&#34;&gt;distributor&amp;rsquo;s otlp_config&lt;/a&gt;. By default, the following resource attributes will be stored as index labels, while the remaining attributes are stored as &lt;a href=&#34;../../get-started/labels/structured-metadata/&#34;&gt;Structured Metadata&lt;/a&gt; with each log entry:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;cloud.availability_zone&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;cloud.region&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;container.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;deployment.environment.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.cluster.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.container.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.cronjob.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.daemonset.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.deployment.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.job.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.namespace.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.pod.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.replicaset.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8s.statefulset.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;service.instance.id&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;service.name&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;service.namespace&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Because Loki has a default limit of 15 index labels, we recommend storing only select resource attributes as index labels. Although the default config selects more than 15 Resource Attributes, it should be fine since a few are mutually exclusive.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;



&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;For Grafana Cloud Logs, see the &lt;a href=&#34;/docs/grafana-cloud/send-data/otlp/otlp-format-considerations/#logs&#34;&gt;current OpenTelemetry guidance&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Timestamp: One of &lt;code&gt;LogRecord.TimeUnixNano&lt;/code&gt; or &lt;code&gt;LogRecord.ObservedTimestamp&lt;/code&gt;, based on which one is set. If both are not set, the ingestion timestamp will be used.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LogLine: &lt;code&gt;LogRecord.Body&lt;/code&gt; holds the body of the log. However, since Loki only supports Log body in string format, we will stringify non-string values using the &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector/blob/ab3d6c5b64701e690aaa340b0a63f443ff22c1f0/pdata/pcommon/value.go#L353&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;AsString method from the OTel collector lib&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../get-started/labels/structured-metadata/&#34;&gt;Structured Metadata&lt;/a&gt;: Anything which can’t be stored in Index labels and LogLine would be stored as Structured Metadata. Here is a non-exhaustive list of what will be stored in Structured Metadata to give a sense of what it will hold:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Resource Attributes not stored as Index labels is replicated and stored with each log entry.&lt;/li&gt;
&lt;li&gt;Everything under InstrumentationScope is replicated and stored with each log entry.&lt;/li&gt;
&lt;li&gt;Everything under LogRecord except &lt;code&gt;LogRecord.Body&lt;/code&gt;, &lt;code&gt;LogRecord.TimeUnixNano&lt;/code&gt; and sometimes &lt;code&gt;LogRecord.ObservedTimestamp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The default list of resource attributes to store as labels can be configured using &lt;code&gt;default_resource_attributes_as_index_labels&lt;/code&gt; under the 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/#distributor&#34;&gt;distributor&amp;rsquo;s otlp_config&lt;/a&gt;. You can set global limits using 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/#limits_config&#34;&gt;limits_config.otlp_config&lt;/a&gt;. If you are using Grafana Cloud, contact support to configure this setting.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;Because of the potential for high 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/labels/cardinality/&#34;&gt;cardinality&lt;/a&gt;, &lt;code&gt;k8s.pod.name&lt;/code&gt; and &lt;code&gt;service.instance.id&lt;/code&gt; are no longer recommended as default labels. But because removing these resource attributes from the default labels would be a breaking change for existing users, they have not yet been deprecated as default labels. If you are a new user of Grafana Loki, we recommend that you modify your Alloy or OpenTelemetry Collector configuration to convert &lt;code&gt;k8s.pod.name&lt;/code&gt; and &lt;code&gt;service.instance.id&lt;/code&gt; from index labels to structured metadata.
For sample configurations, refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/labels/remove-default-labels/&#34;&gt;Remove default labels&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Things to note before ingesting OpenTelemetry logs to Loki:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dots (.) are converted to underscores (_).&lt;/p&gt;
&lt;p&gt;Loki does not support &lt;code&gt;.&lt;/code&gt; or any other special characters other than &lt;code&gt;_&lt;/code&gt; in label names. The unsupported characters are replaced with an &lt;code&gt;_&lt;/code&gt; while converting Attributes to Index Labels or Structured Metadata.
Also, please note that while writing the queries, you must use the normalized format, i.e. use &lt;code&gt;_&lt;/code&gt; instead of special characters while querying data using OTel Attributes.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;service.name&lt;/code&gt; in OTLP would become &lt;code&gt;service_name&lt;/code&gt; in Loki.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flattening of nested Attributes&lt;/p&gt;
&lt;p&gt;While converting Attributes in OTLP to Index labels or Structured Metadata, any nested attribute values are flattened out using &lt;code&gt;_&lt;/code&gt; as a separator.
It is done in a similar way as to how it is done in the 
    &lt;a href=&#34;/docs/loki/v3.7.x/query/log_queries/#json&#34;&gt;LogQL json parser&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stringification of non-string Attribute values&lt;/p&gt;
&lt;p&gt;While converting Attribute values in OTLP to Index label values or Structured Metadata, any non-string values are converted to string using &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector/blob/ab3d6c5b64701e690aaa340b0a63f443ff22c1f0/pdata/pcommon/value.go#L353&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;AsString method from the OTel collector lib&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;changing-the-default-mapping-of-otlp-to-loki-format&#34;&gt;Changing the default mapping of OTLP to Loki Format&lt;/h3&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Loki supports 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/#limits_config&#34;&gt;per tenant&lt;/a&gt; OTLP config which lets you change the default mapping of OTLP to Loki format for each tenant.
It currently only supports changing the storage of Attributes. Here is what the config looks like:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;# OTLP log ingestion configurations
limits_config:
  otlp_config:
    # Configuration for Resource Attributes to store them as index labels or
    # Structured Metadata or drop them altogether
    resource_attributes:
      # Configure whether to ignore the default list of resource attributes set in
      # &amp;#39;distributor.otlp.default_resource_attributes_as_index_labels&amp;#39; to be
      # stored as index labels and only use the given resource attributes config
      [ignore_defaults: &amp;lt;boolean&amp;gt;]
  
      [attributes_config: &amp;lt;list of attributes_configs&amp;gt;]
  
    # Configuration for Scope Attributes to store them as Structured Metadata or
    # drop them altogether
    [scope_attributes: &amp;lt;list of attributes_configs&amp;gt;]
  
    # Configuration for Log Attributes to store them as Structured Metadata or
    # drop them altogether
    [log_attributes: &amp;lt;list of attributes_configs&amp;gt;]
  
  attributes_config:
    # Configures action to take on matching Attributes. It allows one of
    # [structured_metadata, drop] for all Attribute types. It additionally allows
    # index_label action for Resource Attributes
    [action: &amp;lt;string&amp;gt; | default = &amp;#34;&amp;#34;]
  
    # List of attributes to configure how to store them or drop them altogether
    [attributes: &amp;lt;list of strings&amp;gt;]
  
    # Regex to choose attributes to configure how to store them or drop them
    # altogether
    [regex: &amp;lt;Regexp&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;If you are a Grafana Cloud customer, you can use the &lt;a href=&#34;/docs/grafana-cloud/send-data/logs/config-self-serve/#otlp-label-mappings&#34;&gt;config self-serve API&lt;/a&gt; to configure your OTLP config.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;/div&gt;

        
&lt;p&gt;Here are some example configs to change the default mapping of OTLP to Loki format:&lt;/p&gt;
&lt;h4 id=&#34;example-1&#34;&gt;Example 1&lt;/h4&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;limits_config:
  otlp_config:
    resource_attributes:
      attributes_config:
        - action: index_label
          attributes:
            - service.group&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With the example config, here is how various kinds of Attributes would be stored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Store all 17 Resource Attributes mentioned earlier and &lt;code&gt;service.group&lt;/code&gt; Resource Attribute as index labels.&lt;/li&gt;
&lt;li&gt;Store remaining Resource Attributes as Structured Metadata.&lt;/li&gt;
&lt;li&gt;Store all the Scope and Log Attributes as Structured Metadata.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;example-2&#34;&gt;Example 2&lt;/h4&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;limits_config:
  otlp_config:
    resource_attributes:
      ignore_defaults: true
      attributes_config:
        - action: index_label
          regex: service.group&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With the example config, here is how various kinds of Attributes would be stored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Only&lt;/strong&gt; store &lt;code&gt;service.group&lt;/code&gt; Resource Attribute as index labels.&lt;/li&gt;
&lt;li&gt;Store remaining Resource Attributes as Structured Metadata.&lt;/li&gt;
&lt;li&gt;Store all the Scope and Log Attributes as Structured Metadata.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;example-3&#34;&gt;Example 3&lt;/h4&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;limits_config:
  otlp_config:
    resource_attributes:
      attributes_config:
        - action: index_label
          regex: service.group
    scope_attributes:
      - action: drop
        attributes:
          - method.name
    log_attributes:
      - action: structured_metadata
        attributes:
          - user.id
      - action: drop
        regex: .*&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With the example config, here is how various kinds of Attributes would be stored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Store all 17 Resource Attributes mentioned earlier and &lt;code&gt;service.group&lt;/code&gt; Resource Attribute as index labels.&lt;/li&gt;
&lt;li&gt;Store remaining Resource Attributes as Structured Metadata.&lt;/li&gt;
&lt;li&gt;Drop Scope Attribute named &lt;code&gt;method.name&lt;/code&gt; and store all other Scope Attributes as Structured Metadata.&lt;/li&gt;
&lt;li&gt;Store Log Attribute named &lt;code&gt;user.id&lt;/code&gt; as Structured Metadata and drop all other Log Attributes.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="ingesting-logs-to-loki-using-opentelemetry-collector">Ingesting logs to Loki using OpenTelemetry Collector&lt;/h1>
&lt;div data-shared="otel.md">
&lt;p>Loki natively supports ingesting OpenTelemetry logs over HTTP.
For ingesting logs to Loki using the OpenTelemetry Collector, you must use the &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter" target="_blank" rel="noopener noreferrer">&lt;code>otlphttp&lt;/code> exporter&lt;/a>.&lt;/p></description></item><item><title>Kubernetes Monitoring Helm tutorial</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/k8s-monitoring-helm/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/k8s-monitoring-helm/</guid><content><![CDATA[&lt;!-- INTERACTIVE page intro.md START --&gt;
&lt;h1 id=&#34;kubernetes-monitoring-helm-tutorial&#34;&gt;Kubernetes Monitoring Helm tutorial&lt;/h1&gt;
&lt;p&gt;One of the primary use cases for Loki is to collect and store logs from your &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Kubernetes cluster&lt;/a&gt;. These logs fall into three categories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/cluster-administration/logging/#basic-logging-in-kubernetes&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;strong&gt;Pod logs&lt;/strong&gt;&lt;/a&gt;: Logs generated by pods running in your cluster.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/event-v1/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;strong&gt;Kubernetes Events&lt;/strong&gt;&lt;/a&gt;: Logs generated by the Kubernetes API server.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/cluster-administration/logging/#using-a-node-logging-agent&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;strong&gt;Node logs&lt;/strong&gt;&lt;/a&gt;: Logs generated by the nodes in your cluster.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 75%;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;/media/docs/loki/loki-k8s-logs.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;/media/docs/loki/loki-k8s-logs.png&#34;data-srcset=&#34;/media/docs/loki/loki-k8s-logs.png?w=320 320w, /media/docs/loki/loki-k8s-logs.png?w=550 550w, /media/docs/loki/loki-k8s-logs.png?w=750 750w, /media/docs/loki/loki-k8s-logs.png?w=900 900w, /media/docs/loki/loki-k8s-logs.png?w=1040 1040w, /media/docs/loki/loki-k8s-logs.png?w=1240 1240w, /media/docs/loki/loki-k8s-logs.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;Scraping Kubernetes Logs&#34;width=&#34;1200&#34;height=&#34;900&#34;title=&#34;Scraping Kubernetes Logs&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;/media/docs/loki/loki-k8s-logs.png&#34;
            alt=&#34;Scraping Kubernetes Logs&#34;width=&#34;1200&#34;height=&#34;900&#34;title=&#34;Scraping Kubernetes Logs&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Scraping Kubernetes Logs&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;In this tutorial, we will deploy &lt;a href=&#34;/docs/loki/latest/get-started/overview/&#34;&gt;Loki&lt;/a&gt; and the &lt;a href=&#34;/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/&#34;&gt;Kubernetes Monitoring Helm chart&lt;/a&gt; to collect two of these log types: Pod logs and Kubernetes events. We will also deploy &lt;a href=&#34;/docs/grafana/latest/&#34;&gt;Grafana&lt;/a&gt; to visualize these logs.&lt;/p&gt;
&lt;h2 id=&#34;things-to-know&#34;&gt;Things to know&lt;/h2&gt;
&lt;p&gt;Before you begin, here are some things you should know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Loki&lt;/strong&gt;: Loki can run in a single binary mode or as a distributed system. In this tutorial, we will deploy Loki as a single binary, otherwise known as monolithic mode. Loki can be vertically scaled in this mode depending on the number of logs you are collecting. Grafana Labs recommends running Loki in a distributed/microservice mode for production use cases to monitor high volumes of logs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: You will deploy Loki, Grafana, and Alloy (as part of the Kubernetes Monitoring Helm chart) in the &lt;code&gt;meta&lt;/code&gt; namespace of your Kubernetes cluster. Make sure you have the necessary permissions to create resources in this namespace. These pods will also require resources to run, so consider the amount of capacity your nodes have available. It also possible to just deploy the Kubernetes monitoring Helm chart (since it has a minimal resource footprint) within your cluster and write logs to an external Loki instance or Grafana Cloud.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt;:  In this tutorial, Loki will use the default object storage backend provided in the Loki Helm chart; &lt;a href=&#34;https://min.io/docs/minio/kubernetes/upstream/index.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;MinIO&lt;/a&gt;. You should migrate to a more production-ready storage backend like &lt;a href=&#34;https://aws.amazon.com/s3/getting-started/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;S3&lt;/a&gt;, &lt;a href=&#34;https://cloud.google.com/storage/docs&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;GCS&lt;/a&gt;, &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/storage/blobs/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Azure Blob Storage&lt;/a&gt; or a MinIO Cluster for production use cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- INTERACTIVE ignore START --&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before you begin, you will need the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Kubernetes cluster running version &lt;code&gt;1.23&lt;/code&gt; or later.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;kubectl&lt;/a&gt; installed on your local machine.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://helm.sh/docs/intro/install/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Helm&lt;/a&gt; installed on your local machine.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;Alternatively, you can try out this example in our interactive learning environment: &lt;a href=&#34;https://killercoda.com/grafana-labs/course/loki/k8s-monitoring-helm&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Kubernetes Monitoring with Loki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a fully configured environment with all the dependencies already installed.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/loki/loki-ile.svg&#34;
  alt=&#34;Interactive&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Provide feedback, report bugs, and raise issues in the &lt;a href=&#34;https://github.com/grafana/killercoda&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Grafana Killercoda repository&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;!-- INTERACTIVE ignore END --&gt;
&lt;!-- INTERACTIVE page intro.md END --&gt;
&lt;!-- INTERACTIVE page step1.md START --&gt;
&lt;h2 id=&#34;create-the-meta-and-prod-namespaces&#34;&gt;Create the &lt;code&gt;meta&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt; namespaces&lt;/h2&gt;
&lt;p&gt;The K8s Monitoring Helm chart will monitor two namespaces: &lt;code&gt;meta&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;meta&lt;/code&gt; namespace: This namespace will be used to deploy Loki, Grafana, and Alloy.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prod&lt;/code&gt; namespace: This namespace will be used to deploy the sample application that will generate logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create the &lt;code&gt;meta&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt; namespaces by running the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create namespace meta &amp;amp;&amp;amp; kubectl create namespace prod&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- INTERACTIVE page step1.md END --&gt;
&lt;!-- INTERACTIVE page step2.md START --&gt;
&lt;h2 id=&#34;add-the-grafana-helm-repository&#34;&gt;Add the Grafana Helm repository&lt;/h2&gt;
&lt;p&gt;All three Helm charts (Loki, Grafana, and the Kubernetes Monitoring Helm) are available in the Grafana Helm repository. Add the Grafana Helm repository by running the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo add grafana https://grafana.github.io/helm-charts &amp;amp;&amp;amp; helm repo update&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As well as adding the repo to your local helm list, you should also run &lt;code&gt;helm repo update&lt;/code&gt; to ensure you have the latest version of the charts.&lt;/p&gt;
&lt;h2 id=&#34;clone-the-tutorial-repository&#34;&gt;Clone the tutorial repository&lt;/h2&gt;
&lt;p&gt;Clone the tutorial repository by running the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;git clone https://github.com/grafana/alloy-scenarios.git&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then change directories to the &lt;code&gt;alloy-scenarios/k8s/logs&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;cd alloy-scenarios/k8s/logs&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;The rest of this tutorial assumes you are in the &lt;code&gt;alloy-scenarios/k8s/logs&lt;/code&gt; directory.&lt;/strong&gt;&lt;/p&gt;
&lt;!-- INTERACTIVE page step2.md END --&gt;
&lt;!-- INTERACTIVE page step3.md START --&gt;
&lt;h2 id=&#34;deploy-loki&#34;&gt;Deploy Loki&lt;/h2&gt;
&lt;p&gt;Grafana Loki will be used to store our collected logs. In this tutorial we will deploy Loki with a minimal footprint and use the default storage backend provided by the Loki Helm chart, MinIO.&lt;/p&gt;

&lt;p&gt;To deploy Loki run the following command:&lt;/p&gt;
&lt;!-- INTERACTIVE ignore START --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --values loki-values.yml loki grafana/loki -n meta&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- INTERACTIVE ignore END --&gt;

&lt;p&gt;This command will deploy Loki in the &lt;code&gt;meta&lt;/code&gt; namespace. The command also includes a &lt;code&gt;values&lt;/code&gt; file that specifies the configuration for Loki. For more details on how to configure the Loki Helm chart refer to the Loki Helm 
    &lt;a href=&#34;/docs/loki/v3.7.x/setup/install/helm/&#34;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;!-- INTERACTIVE page step3.md END --&gt;
&lt;!-- INTERACTIVE page step4.md START --&gt;
&lt;h2 id=&#34;deploy-grafana&#34;&gt;Deploy Grafana&lt;/h2&gt;
&lt;p&gt;Next we will deploy Grafana to the &lt;code&gt;meta&lt;/code&gt; namespace. You will use Grafana to visualize the logs stored in Loki. To deploy Grafana run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --values grafana-values.yml grafana grafana/grafana --namespace meta&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As before, the command also includes a &lt;code&gt;values&lt;/code&gt; file that specifies the configuration for Grafana. There are two important configuration attributes to take note of:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;adminUser&lt;/code&gt; and &lt;code&gt;adminPassword&lt;/code&gt;: These are the credentials you will use to log in to Grafana. The values are &lt;code&gt;admin&lt;/code&gt; and &lt;code&gt;adminadminadmin&lt;/code&gt; respectively. The recommended practice is to either use a Kubernetes secret or allow Grafana to generate a password for you. For more details on how to configure the Grafana Helm chart, refer to the Grafana Helm 
    &lt;a href=&#34;/docs/grafana/latest/installation/helm/&#34;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;datasources&lt;/code&gt;: This section of the configuration lets you define the data sources that Grafana should use. In this tutorial, you will define a Loki data source. The data source is defined as follows:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt; datasources:
   datasources.yaml:
     apiVersion: 1
     datasources:
     - name: Loki
       type: loki
       access: proxy
       orgId: 1
       url: http://loki-gateway.meta.svc.cluster.local:80
       basicAuth: false
       isDefault: false
       version: 1
       editable: false&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This configuration defines a data source named &lt;code&gt;Loki&lt;/code&gt; that Grafana will use to query logs stored in Loki. The &lt;code&gt;url&lt;/code&gt; attribute specifies the URL of the Loki gateway. The Loki gateway is a service that sits in front of the Loki API and provides a single endpoint for ingesting and querying logs. The URL is in the format &lt;code&gt;http://loki-gateway.&amp;lt;NAMESPACE&amp;gt;.svc.cluster.local:80&lt;/code&gt;. The &lt;code&gt;loki-gateway&lt;/code&gt; service is created by the Loki Helm chart and is used to query logs stored in Loki. &lt;strong&gt;If you choose to deploy Loki in a different namespace or with a different name, you will need to update the &lt;code&gt;url&lt;/code&gt; attribute accordingly.&lt;/strong&gt;&lt;/p&gt;
&lt;!-- INTERACTIVE page step4.md END --&gt;
&lt;!-- INTERACTIVE page step5.md START --&gt;
&lt;h2 id=&#34;deploy-the-kubernetes-monitoring-helm-chart&#34;&gt;Deploy the Kubernetes Monitoring Helm chart&lt;/h2&gt;
&lt;p&gt;The Kubernetes Monitoring Helm chart is used for gathering, scraping, and forwarding Kubernetes telemetry data to a Grafana stack. This includes the ability to collect metrics, logs, traces, and continuous profiling data. The scope of this tutorial is to deploy the Kubernetes Monitoring Helm chart to collect pod logs and Kubernetes events.&lt;/p&gt;
&lt;p&gt;To deploy the Kubernetes Monitoring Helm chart run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --values ./k8s-monitoring-values.yml k8s grafana/k8s-monitoring -n meta&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Within the configuration file &lt;code&gt;k8s-monitoring-values.yml&lt;/code&gt; we have defined the following:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;---
cluster:
  name: meta-monitoring-tutorial

destinations:
  - name: loki
    type: loki
    url: http://loki-gateway.meta.svc.cluster.local/loki/api/v1/push


clusterEvents:
  enabled: true
  collector: alloy-logs
  namespaces:
    - meta
    - prod

nodeLogs:
  enabled: false

podLogs:
  enabled: true
  gatherMethod: kubernetesApi
  collector: alloy-logs
  labelsToKeep: [&amp;#34;app_kubernetes_io_name&amp;#34;,&amp;#34;container&amp;#34;,&amp;#34;instance&amp;#34;,&amp;#34;job&amp;#34;,&amp;#34;level&amp;#34;,&amp;#34;namespace&amp;#34;,&amp;#34;service_name&amp;#34;,&amp;#34;service_namespace&amp;#34;,&amp;#34;deployment_environment&amp;#34;,&amp;#34;deployment_environment_name&amp;#34;]
  structuredMetadata:
    pod: pod  # Set structured metadata &amp;#34;pod&amp;#34; from label &amp;#34;pod&amp;#34;
  namespaces:
    - meta
    - prod

# Collectors
alloy-singleton:
  enabled: false

alloy-metrics:
  enabled: false

alloy-logs:
  enabled: true
  # Required when using the Kubernetes API to pod logs
  alloy:
    mounts:
      varlog: false
    clustering:
      enabled: true

alloy-profiles:
  enabled: false

alloy-receiver:
  enabled: false&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To break down the configuration file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Define the cluster name as &lt;code&gt;meta-monitoring-tutorial&lt;/code&gt;. This a static label that will be attached to all logs collected by the Kubernetes Monitoring Helm chart.&lt;/li&gt;
&lt;li&gt;Define a destination named &lt;code&gt;loki&lt;/code&gt; that will be used to forward logs to Loki. The &lt;code&gt;url&lt;/code&gt; attribute specifies the URL of the Loki gateway. &lt;strong&gt;If you choose to deploy Loki in a different namespace or in a different location entirely, you will need to update the &lt;code&gt;url&lt;/code&gt; attribute accordingly.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enable the collection of cluster events and pod logs:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;collector&lt;/code&gt;: specifies which collector to use to collect logs. In this case, we are using the &lt;code&gt;alloy-logs&lt;/code&gt; collector.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labelsToKeep&lt;/code&gt;: specifies the labels to keep when collecting logs. Note this does not drop logs. This is useful when you do not want to apply a high cardanility label. In this case we have removed &lt;code&gt;pod&lt;/code&gt; from the labels to keep.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;structuredMetadata&lt;/code&gt;: specifies the structured metadata to collect. In this case, we are setting the structured metadata &lt;code&gt;pod&lt;/code&gt; so we can retain the pod name for querying. Though it does not need to be indexed as a label.zw&lt;/li&gt;
&lt;li&gt;&lt;code&gt;namespaces&lt;/code&gt;: specifies the namespaces to collect logs from. In this case, we are collecting logs from the &lt;code&gt;meta&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt; namespaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disable the collection of node logs for the purpose of this tutorial as it requires the mounting of &lt;code&gt;/var/log/journal&lt;/code&gt;. This is out of scope for this tutorial.&lt;/li&gt;
&lt;li&gt;Lastly, define the role of the collector. The Kubernetes Monitoring Helm chart will deploy only what you need and nothing more. In this case, we are telling the Helm chart to only deploy Alloy with the capability to collect logs. If you need to collect K8s metrics, traces, or continuous profiling data, you can enable the respective collectors.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- INTERACTIVE page step5.md END --&gt;
&lt;!-- INTERACTIVE page step6.md START --&gt;
&lt;h2 id=&#34;accessing-grafana&#34;&gt;Accessing Grafana&lt;/h2&gt;
&lt;p&gt;To access Grafana, you will need to port-forward the Grafana service to your local machine. To do this, run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;export POD_NAME=$(kubectl get pods --namespace meta -l &amp;#34;app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana&amp;#34; -o jsonpath=&amp;#34;{.items[0].metadata.name}&amp;#34;) &amp;amp;&amp;amp; \
kubectl --namespace meta port-forward $POD_NAME 3000 --address 0.0.0.0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;This will make your terminal unusable until you stop the port-forwarding process. To stop the process, press &lt;code&gt;Ctrl &#43; C&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;This command will port-forward the Grafana service to your local machine on port &lt;code&gt;3000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can now access Grafana by navigating to &lt;a href=&#34;http://localhost:3000&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;http://localhost:3000&lt;/a&gt; in your browser. The default credentials are &lt;code&gt;admin&lt;/code&gt; and &lt;code&gt;adminadminadmin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;One of the first places you should visit is Logs Drilldown which lets you automatically visualize and explore your logs without having to write queries:
&lt;a href=&#34;http://localhost:3000/a/grafana-lokiexplore-app&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;http://localhost:3000/a/grafana-lokiexplore-app&lt;/a&gt;&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 100%;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;/media/docs/loki/k8s-logs-explore-logs.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;/media/docs/loki/k8s-logs-explore-logs.png&#34;data-srcset=&#34;/media/docs/loki/k8s-logs-explore-logs.png?w=320 320w, /media/docs/loki/k8s-logs-explore-logs.png?w=550 550w, /media/docs/loki/k8s-logs-explore-logs.png?w=750 750w, /media/docs/loki/k8s-logs-explore-logs.png?w=900 900w, /media/docs/loki/k8s-logs-explore-logs.png?w=1040 1040w, /media/docs/loki/k8s-logs-explore-logs.png?w=1240 1240w, /media/docs/loki/k8s-logs-explore-logs.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;Logs Drilldown view of K8s logs&#34;width=&#34;2972&#34;height=&#34;1770&#34;title=&#34;Logs Drilldown view of K8s logs&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;/media/docs/loki/k8s-logs-explore-logs.png&#34;
            alt=&#34;Logs Drilldown view of K8s logs&#34;width=&#34;2972&#34;height=&#34;1770&#34;title=&#34;Logs Drilldown view of K8s logs&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Logs Drilldown view of K8s logs&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;!-- INTERACTIVE page step6.md END --&gt;
&lt;!-- INTERACTIVE page step7.md START --&gt;
&lt;h2 id=&#34;optional-view-the-alloy-ui&#34;&gt;(Optional) View the Alloy UI&lt;/h2&gt;
&lt;p&gt;The Kubernetes Monitoring Helm chart deploys Grafana Alloy to collect and forward telemetry data from the Kubernetes cluster. The Helm chart is designed to abstract you away from creating an Alloy configuration file. However if you would like to understand the pipeline you can view the Alloy UI. To access the Alloy UI, you will need to port-forward the Alloy service to your local machine. To do this, run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;export POD_NAME=$(kubectl get pods --namespace meta -l &amp;#34;app.kubernetes.io/name=alloy-logs,app.kubernetes.io/instance=k8s-alloy-logs&amp;#34; -o jsonpath=&amp;#34;{.items[0].metadata.name}&amp;#34;) &amp;amp;&amp;amp; \
kubectl --namespace meta port-forward $POD_NAME 12345 --address 0.0.0.0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;This will make your terminal unusable until you stop the port-forwarding process. To stop the process, press &lt;code&gt;Ctrl &#43; C&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;This command will port-forward the Alloy service to your local machine on port &lt;code&gt;12345&lt;/code&gt;. You can access the Alloy UI by navigating to &lt;a href=&#34;http://localhost:12345&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;http://localhost:12345&lt;/a&gt; in your browser.&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 100%;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;/media/docs/loki/k8s-logs-alloy-ui.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;/media/docs/loki/k8s-logs-alloy-ui.png&#34;data-srcset=&#34;/media/docs/loki/k8s-logs-alloy-ui.png?w=320 320w, /media/docs/loki/k8s-logs-alloy-ui.png?w=550 550w, /media/docs/loki/k8s-logs-alloy-ui.png?w=750 750w, /media/docs/loki/k8s-logs-alloy-ui.png?w=900 900w, /media/docs/loki/k8s-logs-alloy-ui.png?w=1040 1040w, /media/docs/loki/k8s-logs-alloy-ui.png?w=1240 1240w, /media/docs/loki/k8s-logs-alloy-ui.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;Grafana Alloy UI&#34;width=&#34;2968&#34;height=&#34;1562&#34;title=&#34;Grafana Alloy UI&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;/media/docs/loki/k8s-logs-alloy-ui.png&#34;
            alt=&#34;Grafana Alloy UI&#34;width=&#34;2968&#34;height=&#34;1562&#34;title=&#34;Grafana Alloy UI&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Grafana Alloy UI&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;!-- INTERACTIVE page step7.md END --&gt;
&lt;!-- INTERACTIVE page step8.md START --&gt;
&lt;h2 id=&#34;adding-a-sample-application-to-prod&#34;&gt;Adding a sample application to &lt;code&gt;prod&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Finally, lets deploy a sample application to the &lt;code&gt;prod&lt;/code&gt; namespace that will generate some logs. To deploy the sample application run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install tempo grafana/tempo-distributed -n prod&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will deploy a default version of Grafana Tempo to the &lt;code&gt;prod&lt;/code&gt; namespace. Tempo is a distributed tracing backend that is used to store and query traces. Normally Tempo would sit alongside Loki and Grafana in the &lt;code&gt;meta&lt;/code&gt; namespace, but for the purpose of this tutorial, we will pretend this is the primary application generating logs.&lt;/p&gt;
&lt;p&gt;Once deployed lets expose Grafana once more:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;export POD_NAME=$(kubectl get pods --namespace meta -l &amp;#34;app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana&amp;#34; -o jsonpath=&amp;#34;{.items[0].metadata.name}&amp;#34;) &amp;amp;&amp;amp; \
kubectl --namespace meta port-forward $POD_NAME 3000 --address 0.0.0.0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and navigate to &lt;a href=&#34;http://localhost:3000/a/grafana-lokiexplore-app&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;http://localhost:3000/a/grafana-lokiexplore-app&lt;/a&gt; to view Grafana Tempo logs.&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 100%;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;/media/docs/loki/k8s-logs-tempo.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;/media/docs/loki/k8s-logs-tempo.png&#34;data-srcset=&#34;/media/docs/loki/k8s-logs-tempo.png?w=320 320w, /media/docs/loki/k8s-logs-tempo.png?w=550 550w, /media/docs/loki/k8s-logs-tempo.png?w=750 750w, /media/docs/loki/k8s-logs-tempo.png?w=900 900w, /media/docs/loki/k8s-logs-tempo.png?w=1040 1040w, /media/docs/loki/k8s-logs-tempo.png?w=1240 1240w, /media/docs/loki/k8s-logs-tempo.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;Label view of Tempo logs&#34;width=&#34;2978&#34;height=&#34;1476&#34;title=&#34;Label view of Tempo logs&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;/media/docs/loki/k8s-logs-tempo.png&#34;
            alt=&#34;Label view of Tempo logs&#34;width=&#34;2978&#34;height=&#34;1476&#34;title=&#34;Label view of Tempo logs&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Label view of Tempo logs&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;!-- INTERACTIVE page step8.md END --&gt;
&lt;!-- INTERACTIVE page finish.md START --&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you learned how to deploy Loki, Grafana, and the Kubernetes Monitoring Helm chart to collect and store logs from a Kubernetes cluster. We have deployed a minimal test version of each of these Helm charts to demonstrate how quickly you can get started with Loki. It is now worth exploring each of these Helm charts in more detail to understand how to scale them to meet your production needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/setup/install/helm/&#34;&gt;Loki Helm chart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/grafana/latest/installation/helm/&#34;&gt;Grafana Helm chart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/&#34;&gt;Kubernetes Monitoring Helm chart&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- INTERACTIVE page finish.md END --&gt;
]]></content><description>&lt;!-- INTERACTIVE page intro.md START -->
&lt;h1 id="kubernetes-monitoring-helm-tutorial">Kubernetes Monitoring Helm tutorial&lt;/h1>
&lt;p>One of the primary use cases for Loki is to collect and store logs from your &lt;a href="https://kubernetes.io/docs/concepts/overview/" target="_blank" rel="noopener noreferrer">Kubernetes cluster&lt;/a>. These logs fall into three categories:&lt;/p></description></item><item><title>Promtail agent</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/promtail/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/promtail/</guid><content><![CDATA[&lt;h1 id=&#34;promtail-agent&#34;&gt;Promtail agent&lt;/h1&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;Promtail is end of life (EOL) as of March 2, 2026.  Commercial support has ended. No future support or updates will be provided. All future feature development will occur in Grafana Alloy.&lt;br /&gt;
Note that the deprecation of Promtail does NOT include the lambda-promtail client.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;If you are currently using Promtail, you must migrate to Alloy or another supported client.&lt;/p&gt;
&lt;p&gt;The Alloy migration documentation includes a migration tool for converting your Promtail configuration to an Alloy configuration with a single command.&lt;/p&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Links to 
    &lt;a href=&#34;/docs/loki/v3.7.x/setup/migrate/migrate-to-alloy/&#34;&gt;Migrate to Alloy documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@syed_usman_ahmed/docker-users-who-use-grafana-loki-with-promtail-need-to-migrate-to-grafana-alloy-as-promtail-the-a20a&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Medium post with migration instructions&lt;/a&gt; written by a Grafana Developer Advocate.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=3W99Go4S39E&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Video for Docker users with Promtail migration guide&lt;/a&gt; filmed by a Grafana Developer Advocate.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="promtail-agent">Promtail agent&lt;/h1>
&lt;div class="admonition admonition-warning">&lt;blockquote>&lt;p class="title text-uppercase">Warning&lt;/p>&lt;p>Promtail is end of life (EOL) as of March 2, 2026. Commercial support has ended. No future support or updates will be provided. All future feature development will occur in Grafana Alloy.&lt;br />
Note that the deprecation of Promtail does NOT include the lambda-promtail client.&lt;/p></description></item><item><title>Docker driver client</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/docker-driver/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/docker-driver/</guid><content><![CDATA[&lt;h1 id=&#34;docker-driver-client&#34;&gt;Docker driver client&lt;/h1&gt;
&lt;p&gt;Grafana Loki officially supports a Docker plugin that will read logs from Docker
containers and ship them to Loki. The plugin can be configured to send the logs
to a private Loki instance or Grafana Cloud.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Docker plugins are not supported on Windows; see the &lt;a href=&#34;https://docs.docker.com/engine/extend&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Docker Engine managed plugin system&lt;/a&gt; documentation for more information.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Documentation on configuring the Loki Docker Driver can be found on the 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/docker-driver/configuration/&#34;&gt;configuration page&lt;/a&gt;.
If you have any questions or issues using the Docker plugin, open an issue in
the &lt;a href=&#34;https://github.com/grafana/loki/issues&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Loki repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;install-the-docker-driver-client&#34;&gt;Install the Docker driver client&lt;/h2&gt;
&lt;p&gt;The Docker plugin must be installed on each Docker host that will be running containers you want to collect logs from.&lt;/p&gt;
&lt;p&gt;Run the following command to install the plugin, updating the release version, or changing the architecture (&lt;code&gt;arm64&lt;/code&gt; and &lt;code&gt;amd64&lt;/code&gt; are currently supported), if needed:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker plugin install grafana/loki-docker-driver:3.7.0-arm64 --alias loki --grant-all-permissions&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Add &lt;code&gt;-arm64&lt;/code&gt; to the image tag for ARM64 hosts.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To check installed plugins, use the &lt;code&gt;docker plugin ls&lt;/code&gt; command.
Plugins that have started successfully are listed as enabled:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker plugin ls&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see output similar to the following:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;ID                  NAME         DESCRIPTION           ENABLED
ac720b8fcfdb        loki         Loki Logging Driver   true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Once you have successfully installed the plugin you can 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/docker-driver/configuration/&#34;&gt;configure&lt;/a&gt; it.&lt;/p&gt;
&lt;h2 id=&#34;upgrade-the-docker-driver-client&#34;&gt;Upgrade the Docker driver client&lt;/h2&gt;
&lt;p&gt;The upgrade process involves disabling the existing plugin, upgrading (chaning version and architecture as needed), then
re-enabling and restarting Docker:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker plugin disable loki --force
docker plugin upgrade loki grafana/loki-docker-driver:3.7.0-arm64 --grant-all-permissions
docker plugin enable loki
systemctl restart docker&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Update the version number to the appropriate version.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;uninstall-the-docker-driver-client&#34;&gt;Uninstall the Docker driver client&lt;/h2&gt;
&lt;p&gt;To cleanly uninstall the plugin, disable and remove it:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker plugin disable loki --force
docker plugin rm loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;known-issue-deadlocked-docker-daemon&#34;&gt;Known Issue: Deadlocked Docker Daemon&lt;/h2&gt;
&lt;p&gt;The driver keeps all logs in memory and will drop log entries if Loki is not reachable and if the quantity of &lt;code&gt;max_retries&lt;/code&gt; has been exceeded. To avoid the dropping of log entries, setting &lt;code&gt;max_retries&lt;/code&gt; to zero allows unlimited retries; the driver will continue trying forever until Loki is again reachable. Trying forever may have undesired consequences, because the Docker daemon will wait for the Loki driver to process all logs of a container, until the container is removed. Thus, the Docker daemon might wait forever if the container is stuck.&lt;/p&gt;
&lt;p&gt;The wait time can be lowered by setting &lt;code&gt;loki-retries=2&lt;/code&gt;, &lt;code&gt;loki-max-backoff=800ms&lt;/code&gt;, &lt;code&gt;loki-timeout=1s&lt;/code&gt; and &lt;code&gt;keep-file=true&lt;/code&gt;. This way the daemon will be locked only for a short time and the logs will be persisted locally when the Loki client is unable to re-connect.&lt;/p&gt;
&lt;p&gt;Also you can use non-blocking mode by setting &lt;code&gt;services.logger.logging.options.mode=non-blocking&lt;/code&gt; in your &lt;code&gt;docker-compose&lt;/code&gt; file. Non-blocking means that the process of writing logs to Loki will not block the main flow of an application or service if Loki is temporarily unavailable or unable to process log messages. In non-blocking mode, log messages will be buffered and sent to Loki asynchronously, which allows the main thread to continue working without delay. If Loki is unavailable, log messages will be stored in a buffer and sent when Loki becomes available again. However, this setting is useful to prevent blocking the main flow of an application or service due to logging issues, but it can also lead to loss of log messages if the buffer overflows or if Loki is unavailable for a long time.&lt;/p&gt;
&lt;p&gt;To avoid this issue, use the Alloy &lt;a href=&#34;/docs/alloy/latest/reference/components/loki/loki.source.docker/&#34;&gt;&lt;code&gt;loki.source.docker&lt;/code&gt;&lt;/a&gt; component or &lt;a href=&#34;/docs/alloy/latest/reference/components/discovery/discovery.docker/&#34;&gt;&lt;code&gt;discovery.docker&lt;/code&gt;&lt;/a&gt; for Docker service discovery.&lt;/p&gt;
]]></content><description>&lt;h1 id="docker-driver-client">Docker driver client&lt;/h1>
&lt;p>Grafana Loki officially supports a Docker plugin that will read logs from Docker
containers and ship them to Loki. The plugin can be configured to send the logs
to a private Loki instance or Grafana Cloud.&lt;/p></description></item><item><title>Fluent Bit</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/fluentbit/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/fluentbit/</guid><content><![CDATA[&lt;h1 id=&#34;fluent-bit&#34;&gt;Fluent Bit&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://fluentbit.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Fluent Bit&lt;/a&gt; is a fast, lightweight logs and metrics agent. It is a CNCF graduated sub-project under the umbrella of Fluentd. Fluent Bit is licensed under the terms of the Apache License v2.0.&lt;/p&gt;
&lt;p&gt;When using Fluent Bit to ship logs to Loki, you can define which log files you want to collect using the &lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/inputs/tail&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;Tail&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/inputs/standard-input&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;Stdin&lt;/code&gt;&lt;/a&gt; data pipeline input. Additionally, Fluent Bit supports multiple &lt;code&gt;Filter&lt;/code&gt; and &lt;code&gt;Parser&lt;/code&gt; plugins (&lt;code&gt;Kubernetes&lt;/code&gt;, &lt;code&gt;JSON&lt;/code&gt;, etc.) to structure and alter log lines.&lt;/p&gt;
&lt;p&gt;There are two Fluent Bit plugins for Loki:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The integrated &lt;code&gt;loki&lt;/code&gt; 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/fluentbit/fluent-bit-plugin/&#34;&gt;plugin&lt;/a&gt;, which is officially maintained by the Fluent Bit project.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;grafana-loki&lt;/code&gt; 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/fluentbit/community-plugin/&#34;&gt;plugin&lt;/a&gt;, an alternative community plugin by Grafana Labs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We recommend using the &lt;code&gt;loki&lt;/code&gt; plugin as this provides the most complete feature set and is actively maintained by the Fluent Bit project.&lt;/p&gt;
&lt;h2 id=&#34;tutorial&#34;&gt;Tutorial&lt;/h2&gt;
&lt;p&gt;To get started with the &lt;code&gt;loki&lt;/code&gt; plugin, follow the 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/fluentbit/fluent-bit-loki-tutorial/&#34;&gt;Sending logs to Loki using Fluent Bit tutorial&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h1 id="fluent-bit">Fluent Bit&lt;/h1>
&lt;p>&lt;a href="https://fluentbit.io/" target="_blank" rel="noopener noreferrer">Fluent Bit&lt;/a> is a fast, lightweight logs and metrics agent. It is a CNCF graduated sub-project under the umbrella of Fluentd. Fluent Bit is licensed under the terms of the Apache License v2.0.&lt;/p></description></item><item><title>Fluentd client</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/fluentd/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/fluentd/</guid><content><![CDATA[&lt;h1 id=&#34;fluentd-client&#34;&gt;Fluentd client&lt;/h1&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.fluentd.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Fluentd output plugin&lt;/a&gt; for Grafana Loki is called
&lt;code&gt;fluent-plugin-grafana-loki&lt;/code&gt; that enables shipping logs to a private Loki
instance or &lt;a href=&#34;/products/cloud/&#34;&gt;Grafana Cloud&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The plugin source code is in the &lt;a href=&#34;https://github.com/grafana/loki/tree/main/clients/cmd/fluentd&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;fluentd directory of the repository&lt;/a&gt;.&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#39;https://www.youtube.com/embed/s43IBSVyTpQ&#39; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;h3 id=&#34;local&#34;&gt;Local&lt;/h3&gt;
&lt;p&gt;To install the plugin use &lt;a href=&#34;https://docs.fluentd.org/deployment/plugin-management&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;fluent-gem&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;fluent-gem install fluent-plugin-grafana-loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;docker-image&#34;&gt;Docker Image&lt;/h2&gt;
&lt;p&gt;The Docker image &lt;code&gt;grafana/fluent-plugin-loki:main&lt;/code&gt; contains &lt;a href=&#34;https://github.com/grafana/loki/tree/main/clients/cmd/fluentd/docker/conf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;default configuration files&lt;/a&gt;. By default, fluentd containers use that default configuration. You can instead specify your &lt;code&gt;fluentd.conf&lt;/code&gt; configuration file with a &lt;code&gt;FLUENTD_CONF&lt;/code&gt; environment variable.&lt;/p&gt;
&lt;p&gt;This image also uses &lt;code&gt;LOKI_URL&lt;/code&gt;, &lt;code&gt;LOKI_USERNAME&lt;/code&gt;, and &lt;code&gt;LOKI_PASSWORD&lt;/code&gt; environment variables to specify the Loki endpoint, user, and password (you can leave the USERNAME and PASSWORD blank if they&amp;rsquo;re not used).&lt;/p&gt;
&lt;p&gt;This image starts an instance of Fluentd that forwards incoming logs to the specified Loki URL. As an alternate, containerized applications can also use &lt;a href=&#34;../docker-driver/&#34;&gt;docker driver plugin&lt;/a&gt; to ship logs without needing Fluentd.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;A Docker Compose configuration that will work looks like:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;services:
  fluentd:
    image: grafana/fluent-plugin-loki:main
    command:
      - &amp;#34;fluentd&amp;#34;
      - &amp;#34;-v&amp;#34;
      - &amp;#34;-p&amp;#34;
      - &amp;#34;/fluentd/plugins&amp;#34;
    environment:
      LOKI_URL: http://loki:3100
      LOKI_USERNAME:
      LOKI_PASSWORD:
    deploy:
      mode: global
    configs:
      - source: loki_config
        target: /fluentd/etc/loki/loki.conf
    networks:
      - loki
    volumes:
      - host_logs:/var/log
      # Needed for journald log ingestion:
      - /etc/machine-id:/etc/machine-id
      - /dev/log:/dev/log
      - /var/run/systemd/journal/:/var/run/systemd/journal/
    logging:
      options:
        tag: infra.monitoring&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Use either &lt;code&gt;&amp;lt;label&amp;gt;...&amp;lt;/label&amp;gt;&lt;/code&gt; or &lt;code&gt;extra_labels&lt;/code&gt; to set at least one label.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;In your Fluentd configuration, add &lt;code&gt;@type loki&lt;/code&gt;. Additional configuration is optional. Default values would look like this:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match **&amp;gt;
  @type loki
  url &amp;#34;https://logs-prod-us-central1.grafana.net&amp;#34;
  username &amp;#34;#{ENV[&amp;#39;LOKI_USERNAME&amp;#39;]}&amp;#34;
  password &amp;#34;#{ENV[&amp;#39;LOKI_PASSWORD&amp;#39;]}&amp;#34;
  extra_labels {&amp;#34;env&amp;#34;:&amp;#34;dev&amp;#34;}
  &amp;lt;buffer&amp;gt;
    flush_interval 10s
    flush_at_shutdown true
  &amp;lt;/buffer&amp;gt;
  buffer_chunk_limit 1m
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;adding-labels&#34;&gt;Adding labels&lt;/h3&gt;
&lt;p&gt;Simple label from top level attribute&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match mytag&amp;gt;
  @type loki
  # ...
  &amp;lt;label&amp;gt;
    fluentd_worker
  &amp;lt;/label&amp;gt;
  # ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can rewrite the label keys as well as the following&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match mytag&amp;gt;
  @type loki
  # ...
  &amp;lt;label&amp;gt;
    worker fluentd_worker
  &amp;lt;/label&amp;gt;
  # ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can use &lt;a href=&#34;https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-record_accessor#syntax&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;record accessor&lt;/a&gt; syntax for nested field.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match mytag&amp;gt;
  @type loki
  # ...
  &amp;lt;label&amp;gt;
    container $.kubernetes.container
  &amp;lt;/label&amp;gt;
  # ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;extracting-kubernetes-labels&#34;&gt;Extracting Kubernetes labels&lt;/h3&gt;
&lt;p&gt;Since Kubernetes labels are a list of nested key-value pairs, a separate option is available to extract them.
Note that special characters like &amp;ldquo;&lt;code&gt;. - /&lt;/code&gt;&amp;rdquo; will be overwritten with &lt;code&gt;_&lt;/code&gt;.
Use with the &lt;code&gt;remove_keys kubernetes&lt;/code&gt; option to eliminate metadata from the log.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match mytag&amp;gt;
  @type loki
  # ...
  extract_kubernetes_labels true
  remove_keys kubernetes
  &amp;lt;label&amp;gt;
    container $.kubernetes.container
  &amp;lt;/label&amp;gt;
  # ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;You can also include automatically all kubernetes labels by using &lt;code&gt;extract_kubernetes_labels true&lt;/code&gt; in your configuration.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;multi-worker-usage&#34;&gt;Multi-worker usage&lt;/h3&gt;
&lt;p&gt;Loki enables out-of-order inserts by default; refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/#accept-out-of-order-writes&#34;&gt;accept out-of-order writes&lt;/a&gt;.
If out-of-order inserts are &lt;em&gt;disabled&lt;/em&gt;, attempting to insert a log entry with an earlier timestamp after a log entry with identical labels but a later timestamp, the insert will fail with &lt;code&gt;HTTP status code: 500, message: rpc error: code = Unknown desc = Entry out of order&lt;/code&gt;. Therefore, in order to use this plugin in a multi worker Fluentd setup, you&amp;rsquo;ll need to include the worker ID in the labels or otherwise &lt;a href=&#34;https://docs.fluentd.org/deployment/multi-process-workers#less-than-worker-n-greater-than-directive&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ensure log streams are always sent to the same worker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, using &lt;a href=&#34;https://github.com/repeatedly/fluent-plugin-record-modifier&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;fluent-plugin-record-modifier&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;filter mytag&amp;gt;
    @type record_modifier
    &amp;lt;record&amp;gt;
        fluentd_worker &amp;#34;#{worker_id}&amp;#34;
    &amp;lt;/record&amp;gt;
&amp;lt;/filter&amp;gt;

&amp;lt;match mytag&amp;gt;
  @type loki
  # ...
  &amp;lt;label&amp;gt;
    fluentd_worker
  &amp;lt;/label&amp;gt;
  # ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;using-multiple-buffer-flush-threads&#34;&gt;Using multiple buffer flush threads&lt;/h3&gt;
&lt;p&gt;Similarly, when using &lt;code&gt;flush_thread_count&lt;/code&gt; &amp;gt; 1 in the &lt;a href=&#34;https://docs.fluentd.org/configuration/buffer-section#flushing-parameters&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;buffer&lt;/code&gt;&lt;/a&gt;
section, a thread identifier must be added as a label to ensure that log chunks flushed in parallel to loki by fluentd always have increasing
times for their unique label sets.&lt;/p&gt;
&lt;p&gt;This plugin automatically adds a &lt;code&gt;fluentd_thread&lt;/code&gt; label with the name of the buffer flush thread when &lt;code&gt;flush_thread_count&lt;/code&gt; &amp;gt; 1.&lt;/p&gt;
&lt;h2 id=&#34;configuration&#34;&gt;Configuration&lt;/h2&gt;
&lt;h3 id=&#34;url&#34;&gt;&lt;code&gt;url&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The URL of the Loki server to send logs to. When sending data, the publish path (&lt;code&gt;../reference/api/loki-http-api/v1/push/&lt;/code&gt;) will automatically be appended.
By default the url is set to &lt;code&gt;https://logs-prod-us-central1.grafana.net&lt;/code&gt;, the url of the Grafana Labs &lt;a href=&#34;/products/cloud/&#34;&gt;hosted Loki&lt;/a&gt; service.&lt;/p&gt;
&lt;h4 id=&#34;proxy-support&#34;&gt;Proxy Support&lt;/h4&gt;
&lt;p&gt;Starting with version 0.8.0, this gem uses &lt;a href=&#34;https://github.com/excon/excon#proxy-support&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;excon, which supports proxy with environment variables&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;username--password&#34;&gt;&lt;code&gt;username&lt;/code&gt; / &lt;code&gt;password&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;If the Loki server requires authentication, specify a username and password.
If using the GrafanaLab&amp;rsquo;s hosted Loki, the username needs to be set to your instanceId and the password should be a Grafana.com api key.&lt;/p&gt;
&lt;h3 id=&#34;tenant&#34;&gt;tenant&lt;/h3&gt;
&lt;p&gt;All requests sent to Loki, a multi-tenant log storage platform, must include a tenant. For some installations the tenant will be set automatically by an authenticating proxy. Otherwise you can define a tenant to be passed through.
The tenant can be any string value.&lt;/p&gt;
&lt;p&gt;The tenant field also supports placeholders, allowing it to dynamically change based on tag and record fields. Each placeholder must be added as a buffer chunk key. The following is an example of setting the tenant based on a Kubernetes pod label:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match **&amp;gt;
  @type loki
  url &amp;#34;https://logs-prod-us-central1.grafana.net&amp;#34;
  tenant ${$.kubernetes.labels.tenant}
  # ...
  &amp;lt;buffer $.kubernetes.labels.tenant&amp;gt;
    @type memory
    flush_interval 5s
  &amp;lt;/buffer&amp;gt;
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;client-certificate-verification&#34;&gt;Client certificate verification&lt;/h3&gt;
&lt;p&gt;If a reverse proxy with client certificate verification is configured in front of Loki, specify a pair of client certificate and private key with &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt;. &lt;code&gt;ca_cert&lt;/code&gt; can also be specified if the server uses custom certificate authority.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match **&amp;gt;
  @type loki

  url &amp;#34;https://loki&amp;#34;

  cert /path/to/certificate.pem
  key /path/to/key.key
  ca_cert /path/to/ca.pem

  ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;server-certificate-verification&#34;&gt;Server certificate verification&lt;/h3&gt;
&lt;p&gt;A flag to disable server certificate verification. By default the &lt;code&gt;insecure_tls&lt;/code&gt; is set to false.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match **&amp;gt;
  @type loki

  url &amp;#34;https://loki&amp;#34;

  insecure_tls true

  ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;compress&#34;&gt;compress&lt;/h3&gt;
&lt;p&gt;Enable compression for the HTTP request body. Supported values: &lt;code&gt;gzip&lt;/code&gt;. Not compressed by default.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;&amp;lt;match **&amp;gt;
  @type loki

  url &amp;#34;https://loki&amp;#34;
  compress gzip

  ...
&amp;lt;/match&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;output-format&#34;&gt;Output format&lt;/h3&gt;
&lt;p&gt;Loki is intended to index and group log streams using only a small set of labels. It is not intended for full-text indexing. When sending logs to Loki the majority of log message will be sent as a single log &amp;ldquo;line&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Several configuration settings are available to control the output format.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;extra_labels: (default: nil) set of labels to include with every Loki stream. eg &lt;code&gt;{&amp;quot;env&amp;quot;:&amp;quot;dev&amp;quot;, &amp;quot;datacenter&amp;quot;: &amp;quot;dc1&amp;quot;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;remove_keys: (default: nil) comma separated list of needless record keys to remove. All other keys will be placed into the log line. You can use &lt;a href=&#34;https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-record_accessor#syntax&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;record_accessor syntax&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;line_format (default:key_value): format to use when flattening the record to a log line. Valid values are &amp;ldquo;json&amp;rdquo; or &amp;ldquo;key_value&amp;rdquo;. If set to &amp;ldquo;json&amp;rdquo; the log line sent to Loki will be the fluentd record (excluding any keys extracted out as labels) dumped as json. If set to &amp;ldquo;key_value&amp;rdquo;, the log line will be each item in the record concatenated together (separated by a single space) in the format &lt;code&gt;&amp;lt;key&amp;gt;=&amp;lt;value&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;drop_single_key: if set to true and a record only has 1 key after extracting &lt;code&gt;&amp;lt;label&amp;gt;&amp;lt;/label&amp;gt;&lt;/code&gt; blocks, set the log line to the value and discard the key.&lt;/li&gt;
&lt;li&gt;include_thread_label (default: true): whether or not to include the fluentd_thread label when multiple threads are used for flushing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;buffer-options&#34;&gt;Buffer options&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;fluentd-plugin-loki&lt;/code&gt; extends &lt;a href=&#34;https://docs.fluentd.org/v1.0/articles/output-plugin-overview&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Fluentd&amp;rsquo;s builtin Output plugin&lt;/a&gt; and use &lt;code&gt;compat_parameters&lt;/code&gt; plugin helper. It adds the following options:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;buffer_type memory
flush_interval 10s
retry_limit 17
retry_wait 1.0
num_threads 1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="fluentd-client">Fluentd client&lt;/h1>
&lt;p>The &lt;a href="https://www.fluentd.org/" target="_blank" rel="noopener noreferrer">Fluentd output plugin&lt;/a> for Grafana Loki is called
&lt;code>fluent-plugin-grafana-loki&lt;/code> that enables shipping logs to a private Loki
instance or &lt;a href="/products/cloud/">Grafana Cloud&lt;/a>.&lt;/p>
&lt;p>The plugin source code is in the &lt;a href="https://github.com/grafana/loki/tree/main/clients/cmd/fluentd" target="_blank" rel="noopener noreferrer">fluentd directory of the repository&lt;/a>.&lt;/p></description></item><item><title>Lambda Promtail client</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/lambda-promtail/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/lambda-promtail/</guid><content><![CDATA[&lt;h1 id=&#34;lambda-promtail-client&#34;&gt;Lambda Promtail client&lt;/h1&gt;
&lt;p&gt;Grafana Loki includes &lt;a href=&#34;https://www.terraform.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Terraform&lt;/a&gt; and &lt;a href=&#34;https://aws.amazon.com/cloudformation/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;CloudFormation&lt;/a&gt; for shipping Cloudwatch, Cloudtrail, VPC Flow Logs and loadbalancer logs to Loki via a &lt;a href=&#34;https://aws.amazon.com/lambda/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;lambda function&lt;/a&gt;. This is done via &lt;a href=&#34;https://github.com/grafana/lambda-promtail&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;lambda-promtail&lt;/a&gt; which processes cloudwatch events and propagates them to Loki (or a Promtail instance) via the push-api &lt;a href=&#34;/docs/loki/latest/send-data/promtail/configuration/#loki_push_api&#34;&gt;scrape config&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;deployment&#34;&gt;Deployment&lt;/h2&gt;
&lt;p&gt;lambda-promtail can easily be deployed via provided &lt;a href=&#34;https://github.com/grafana/lambda-promtail/blob/main/main.tf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Terraform&lt;/a&gt; and &lt;a href=&#34;https://github.com/grafana/lambda-promtail/blob/main/lambda-promtail.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;CloudFormation&lt;/a&gt; files. The Terraform deployment also pulls variable values defined from &lt;a href=&#34;https://github.com/grafana/lambda-promtail/blob/main/variables.tf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;variables.tf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For both deployment types there are a few values that must be defined:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the write address, a Loki Write API compatible endpoint (Loki or Promtail)&lt;/li&gt;
&lt;li&gt;basic auth username/password if the write address is a Loki endpoint and has authentication&lt;/li&gt;
&lt;li&gt;the lambda-promtail image, full ECR repo path:tag&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Terraform deployment also takes in an array of log group and bucket names, and can take arrays for VPC subnets and security groups.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also a flag to keep the log stream label when propagating the logs from Cloudwatch, which defaults to false. This can be helpful when the cardinality is too large, such as the case of a log stream per lambda invocation.&lt;/p&gt;
&lt;p&gt;Additionally, an environment variable can be configured to add extra labels to the logs streamed by lambda-promtail.
These extra labels will take the form &lt;code&gt;__extra_&amp;lt;name&amp;gt;=&amp;lt;value&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An optional environment variable can be configured to add the tenant ID to the logs streamed by lambda-promtail.&lt;/p&gt;
&lt;p&gt;In an effort to make deployment of lambda-promtail as simple as possible, we&amp;rsquo;ve created a &lt;a href=&#34;https://gallery.ecr.aws/grafana/lambda-promtail&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;public ECR repo&lt;/a&gt; to publish our builds of lambda-promtail. Users may clone this repo, make their own modifications to the Go code, and upload their own image to their own ECR repo.&lt;/p&gt;
&lt;h3 id=&#34;examples&#34;&gt;Examples&lt;/h3&gt;
&lt;p&gt;Terraform:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;terraform&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-terraform&#34;&gt;## use cloudwatch log group
terraform apply -var &amp;#34;lambda_promtail_image=&amp;lt;repo:tag&amp;gt;&amp;#34; -var &amp;#34;write_address=https://logs-prod-us-central1.grafana.net/loki/api/v1/push&amp;#34; -var &amp;#34;password=&amp;lt;password&amp;gt;&amp;#34; -var &amp;#34;username=&amp;lt;user&amp;gt;&amp;#34; -var &amp;#39;log_group_names=[&amp;#34;/aws/lambda/log-group-1&amp;#34;, &amp;#34;/aws/lambda/log-group-2&amp;#34;]&amp;#39; -var &amp;#39;bucket_names=[&amp;#34;bucket-a&amp;#34;, &amp;#34;bucket-b&amp;#34;]&amp;#39; -var &amp;#39;batch_size=131072&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;terraform&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-terraform&#34;&gt;## use kinesis data stream
terraform apply -var &amp;#34;&amp;lt;ecr-repo&amp;gt;:&amp;lt;tag&amp;gt;&amp;#34; -var &amp;#34;write_address=https://your-loki-url/loki/api/v1/push&amp;#34; -var &amp;#34;password=&amp;lt;basic-auth-pw&amp;gt;&amp;#34; -var &amp;#34;username=&amp;lt;basic-auth-username&amp;gt;&amp;#34; -var &amp;#39;kinesis_stream_name=[&amp;#34;kinesis-stream-01&amp;#34;, &amp;#34;kinesis-stream-02&amp;#34;]&amp;#39; -var &amp;#39;extra_labels=&amp;#34;name1,value1,name2,value2&amp;#34;&amp;#39; -var &amp;#34;tenant_id=&amp;lt;value&amp;gt;&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The first few lines of &lt;code&gt;main.tf&lt;/code&gt; define the AWS region to deploy to.
Modify as desired, or remove and deploy to&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;terraform&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-terraform&#34;&gt;provider &amp;#34;aws&amp;#34; {
  region = &amp;#34;us-east-2&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To keep the log group label add &lt;code&gt;-var &amp;quot;keep_stream=true&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To add extra labels add &lt;code&gt;-var &#39;extra_labels=&amp;quot;name1,value1,name2,value2&amp;quot;&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To add tenant id add &lt;code&gt;-var &amp;quot;tenant_id=value&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that the creation of a subscription filter on Cloudwatch in the provided Terraform file only accepts an array of log group names.
It does &lt;strong&gt;not&lt;/strong&gt; accept strings for regex filtering on the logs contents via the subscription filters. We suggest extending the Terraform file to do so.
Or, have lambda-promtail write to Promtail and use 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/promtail/stages/drop/&#34;&gt;pipeline stages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;CloudFormation:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;terraform&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-terraform&#34;&gt;aws cloudformation create-stack --stack-name lambda-promtail --template-body file://template.yaml --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM --region us-east-2 --parameters ParameterKey=WriteAddress,ParameterValue=https://logs-prod-us-central1.grafana.net/loki/api/v1/push ParameterKey=Username,ParameterValue=&amp;lt;user&amp;gt; ParameterKey=Password,ParameterValue=&amp;lt;password&amp;gt; ParameterKey=LambdaPromtailImage,ParameterValue=&amp;lt;repo:tag&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Within the CloudFormation template file, copy, paste, and modify the subscription filter section as needed for each log group:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;terraform&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-terraform&#34;&gt;MainLambdaPromtailSubscriptionFilter:
  Type: AWS::Logs::SubscriptionFilter
  Properties:
    DestinationArn: !GetAtt LambdaPromtailFunction.Arn
    FilterPattern: &amp;#34;&amp;#34;
    LogGroupName: &amp;#34;/aws/lambda/some-lambda-log-group&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To keep the log group label, add &lt;code&gt;ParameterKey=KeepStream,ParameterValue=true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To add extra labels, include &lt;code&gt;ParameterKey=ExtraLabels,ParameterValue=&amp;quot;name1,value1,name2,value2&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To add a tenant ID, add &lt;code&gt;ParameterKey=TenantID,ParameterValue=value&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To modify an existing CloudFormation stack, use &lt;a href=&#34;https://docs.aws.amazon.com/cli/latest/reference/cloudformation/update-stack.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;update-stack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If using CloudFormation to write your infrastructure code, you should consider the &lt;a href=&#34;#s3-based-logging-and-cloudformation&#34;&gt;EventBridge based solution&lt;/a&gt; for easier deployment.&lt;/p&gt;
&lt;h2 id=&#34;uses&#34;&gt;Uses&lt;/h2&gt;
&lt;h3 id=&#34;ephemeral-jobs&#34;&gt;Ephemeral Jobs&lt;/h3&gt;
&lt;p&gt;This workflow is intended to be an effective approach for monitoring ephemeral jobs such as those run on AWS Lambda which are otherwise hard/impossible to monitor via one of the other Loki &lt;a href=&#34;../&#34;&gt;clients&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ephemeral jobs can quite easily run afoul of cardinality best practices. During high request load, an AWS lambda function might balloon in concurrency, creating many log streams in Cloudwatch. For this reason lambda-promtail defaults to &lt;strong&gt;not&lt;/strong&gt; keeping the log stream value as a label when propagating the logs to Loki. This is only possible because new versions of Loki no longer have an ingestion ordering constraint on logs within a single stream.&lt;/p&gt;
&lt;h3 id=&#34;proof-of-concept-loki-deployments&#34;&gt;Proof of concept Loki deployments&lt;/h3&gt;
&lt;p&gt;For those using Cloudwatch and wishing to test out Loki in a low-risk way, this workflow allows piping Cloudwatch logs to Loki regardless of the event source (EC2, Kubernetes, Lambda, ECS, etc) without setting up a set of Promtail daemons across their infrastructure. However, running Promtail as a daemon on your infrastructure is the best-practice deployment strategy in the long term for flexibility, reliability, performance, and cost.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Propagating logs from Cloudwatch to Loki means you&amp;rsquo;ll still need to &lt;em&gt;pay&lt;/em&gt; for Cloudwatch.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;vpc-flow-logs&#34;&gt;VPC Flow logs&lt;/h3&gt;
&lt;p&gt;This workflow allows ingesting AWS VPC Flow logs from s3.&lt;/p&gt;
&lt;p&gt;One thing to be aware of with this is that the default flow log format doesn&amp;rsquo;t have a timestamp, so the log timestamp will be set to the time the lambda starts processing the log file.&lt;/p&gt;
&lt;h3 id=&#34;loadbalancer-logs&#34;&gt;Loadbalancer logs&lt;/h3&gt;
&lt;p&gt;This workflow allows ingesting AWS Application/Network Load Balancer logs stored on S3 to Loki.&lt;/p&gt;
&lt;h3 id=&#34;cloudtrail-logs&#34;&gt;Cloudtrail logs&lt;/h3&gt;
&lt;p&gt;This workflow allows ingesting AWS Cloudtrail logs stored on S3 to Loki.&lt;/p&gt;
&lt;h3 id=&#34;cloudfront-logs&#34;&gt;Cloudfront logs&lt;/h3&gt;
&lt;p&gt;Cloudfront logs can be either batched or streamed in real time to Loki:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logging can be activated on a Cloudfront distribution with an S3 bucket as the destination. In this case, the workflow is the same as for other services (VPC Flow logs, Loadbalancer logs, Cloudtrail logs).&lt;/li&gt;
&lt;li&gt;Cloudfront &lt;a href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/real-time-logs.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;real-time logs&lt;/a&gt; can be sent to a Kinesis data stream. The data stream can be mapped to be an &lt;a href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;event source&lt;/a&gt; for lambda-promtail to deliver the logs to Loki.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;triggering-lambda-promtail-via-sqs&#34;&gt;Triggering Lambda-Promtail via SQS&lt;/h3&gt;
&lt;p&gt;For AWS services supporting sending messages to SQS (for example, S3 with an S3 Notification to SQS), events can be processed through an &lt;a href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;SQS queue using a lambda trigger&lt;/a&gt; instead of directly configuring the source service to trigger lambda. Lambda-promtail will retrieve the nested events from the SQS messages&amp;rsquo; body and process them as if them came directly from the source service.&lt;/p&gt;
&lt;h3 id=&#34;on-failure-log-recovery-using-sqs&#34;&gt;On-Failure log recovery using SQS&lt;/h3&gt;
&lt;p&gt;Triggering lambda-promtail through SQS allows handling on-failure recovery of the logs using a secondary SQS queue as a dead-letter-queue (DLQ). You can configure lambda so that unsuccessfully processed messages will be sent to the DLQ. After fixing the issue, operators will be able to reprocess the messages by sending back messages from the DLQ to the source queue using the &lt;a href=&#34;https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue-redrive.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;SQS DLQ redrive&lt;/a&gt; feature.&lt;/p&gt;
&lt;h3 id=&#34;s3-based-logging-and-cloudformation&#34;&gt;S3 based logging and CloudFormation&lt;/h3&gt;
&lt;p&gt;Lambda-promtail lets you send logs from different services that use S3 as their logs destination (ALB, VPC Flow, CloudFront access logs, etc.). For this, you need to configure S3 bucket notifications to trigger the lambda-promtail deployment. However, when using CloudFormation to encode infrastructure, there is a &lt;a href=&#34;https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/79&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;known issue&lt;/a&gt; when configuring &lt;code&gt;AWS::S3::BucketNotification&lt;/code&gt; and the resource that will be triggered by the notification in the same stack.&lt;/p&gt;
&lt;p&gt;To manage this issue, AWS introduced &lt;a href=&#34;https://aws.amazon.com/blogs/aws/new-use-amazon-s3-event-notifications-with-amazon-eventbridge/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;S3 event notifications with Event Bridge&lt;/a&gt;. When an object gets created in a S3 bucket, this sends an event to an EventBridge bus, and you can create a rule to send those events to Lambda-promtail.&lt;/p&gt;
&lt;p&gt;The diagram below shows how notifications logs will be written from the source service into an S3 bucket. From there on, the S3 bucket will send an &lt;code&gt;Object created&lt;/code&gt; notification into the EventBridge &lt;code&gt;default&lt;/code&gt; bus, where we can configure a rule to trigger Lambda Promtail.&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 598px;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link&#34;
        href=&#34;https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload &#34;
          data-src=&#34;https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png&#34;data-srcset=&#34;https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=320 320w, https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=550 550w, https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=750 750w, https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=900 900w, https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=1040 1040w, https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=1240 1240w, https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;The diagram shows how notifications logs are written from the source service into an S3 bucket&#34;width=&#34;598&#34;height=&#34;332&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;https://grafana.com/media/docs/loki/lambda-promtail-with-eventbridge.png&#34;
            alt=&#34;The diagram shows how notifications logs are written from the source service into an S3 bucket&#34;width=&#34;598&#34;height=&#34;332&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/grafana/lambda-promtail/blob/main/aws-eventbridge-logs.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;template-eventbridge.yaml&lt;/a&gt; CloudFormation template configures Lambda-promtail with EventBridge to address this known issue. To deploy the template, use the snippet below, completing appropriately the &lt;code&gt;ParameterValue&lt;/code&gt; arguments.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;aws cloudformation create-stack \
  --stack-name lambda-promtail-stack \
  --template-body file://template-eventbridge.yaml \
  --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
  --region us-east-2 \
  --parameters ParameterKey=WriteAddress,ParameterValue=https://your-loki-url/loki/api/v1/push ParameterKey=Username,ParameterValue=&amp;lt;basic-auth-username&amp;gt; ParameterKey=Password,ParameterValue=&amp;lt;basic-auth-pw&amp;gt; ParameterKey=BearerToken,ParameterValue=&amp;lt;bearer-token&amp;gt; ParameterKey=LambdaPromtailImage,ParameterValue=&amp;lt;ecr-repo&amp;gt;:&amp;lt;tag&amp;gt; ParameterKey=ExtraLabels,ParameterValue=&amp;#34;name1,value1,name2,value2&amp;#34; ParameterKey=TenantID,ParameterValue=&amp;lt;value&amp;gt; ParameterKey=SkipTlsVerify,ParameterValue=&amp;#34;false&amp;#34; ParameterKey=EventSourceS3Bucket,ParameterValue=&amp;lt;S3 where target logs are stored&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;propagated-labels&#34;&gt;Propagated Labels&lt;/h2&gt;
&lt;p&gt;Incoming logs can have seven special labels assigned to them which can be used in 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/promtail/configuration/#relabel_configs&#34;&gt;relabeling&lt;/a&gt; or later stages in a Promtail 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/promtail/pipelines/&#34;&gt;pipeline&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;__aws_log_type&lt;/code&gt;: Where this log came from (Cloudwatch, Kinesis or S3).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__aws_cloudwatch_log_group&lt;/code&gt;: The associated Cloudwatch Log Group for this log.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__aws_cloudwatch_log_stream&lt;/code&gt;: The associated Cloudwatch Log Stream for this log (if &lt;code&gt;KEEP_STREAM=true&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__aws_cloudwatch_owner&lt;/code&gt;: The AWS ID of the owner of this event.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__aws_kinesis_event_source_arn&lt;/code&gt;: The Kinesis event source ARN.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__aws_s3_log_lb&lt;/code&gt;: The name of the loadbalancer.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__aws_s3_log_lb_owner&lt;/code&gt;: The Account ID of the loadbalancer owner.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;relabeling-configuration&#34;&gt;Relabeling Configuration&lt;/h2&gt;
&lt;p&gt;Lambda-promtail supports Prometheus-style relabeling through the &lt;code&gt;RELABEL_CONFIGS&lt;/code&gt; environment variable. This allows you to modify, keep, or drop labels before sending logs to Loki. The configuration is provided as a JSON array of relabel configurations. The relabeling functionality follows the same principles as Prometheus relabeling - for a detailed explanation of how relabeling works, see &lt;a href=&#34;/blog/2022/03/21/how-relabeling-in-prometheus-works/&#34;&gt;How relabeling in Prometheus works&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Example configurations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rename a label and capture regex groups:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;RELABEL_CONFIGS&amp;#34;: [
    {
      &amp;#34;source_labels&amp;#34;: [&amp;#34;__aws_log_type&amp;#34;],
      &amp;#34;target_label&amp;#34;: &amp;#34;log_type&amp;#34;,
      &amp;#34;action&amp;#34;: &amp;#34;replace&amp;#34;,
      &amp;#34;regex&amp;#34;: &amp;#34;(.*)&amp;#34;,
      &amp;#34;replacement&amp;#34;: &amp;#34;${1}&amp;#34;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Keep only specific log types (useful for filtering):&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;RELABEL_CONFIGS&amp;#34;: [
    {
      &amp;#34;source_labels&amp;#34;: [&amp;#34;__aws_log_type&amp;#34;],
      &amp;#34;regex&amp;#34;: &amp;#34;s3_.*&amp;#34;,
      &amp;#34;action&amp;#34;: &amp;#34;keep&amp;#34;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Drop internal AWS labels (cleanup):&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;RELABEL_CONFIGS&amp;#34;: [
    {
      &amp;#34;regex&amp;#34;: &amp;#34;__aws_.*&amp;#34;,
      &amp;#34;action&amp;#34;: &amp;#34;labeldrop&amp;#34;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Multiple relabeling rules (combining different actions):&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;RELABEL_CONFIGS&amp;#34;: [
    {
      &amp;#34;source_labels&amp;#34;: [&amp;#34;__aws_log_type&amp;#34;],
      &amp;#34;target_label&amp;#34;: &amp;#34;log_type&amp;#34;,
      &amp;#34;action&amp;#34;: &amp;#34;replace&amp;#34;,
      &amp;#34;regex&amp;#34;: &amp;#34;(.*)&amp;#34;,
      &amp;#34;replacement&amp;#34;: &amp;#34;${1}&amp;#34;
    },
    {
      &amp;#34;source_labels&amp;#34;: [&amp;#34;__aws_s3_log_lb&amp;#34;],
      &amp;#34;target_label&amp;#34;: &amp;#34;loadbalancer&amp;#34;,
      &amp;#34;action&amp;#34;: &amp;#34;replace&amp;#34;
    },
    {
      &amp;#34;regex&amp;#34;: &amp;#34;__aws_.*&amp;#34;,
      &amp;#34;action&amp;#34;: &amp;#34;labeldrop&amp;#34;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;supported-actions&#34;&gt;Supported Actions&lt;/h3&gt;
&lt;p&gt;The following actions are supported, matching Prometheus relabeling capabilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;replace&lt;/code&gt;: Replace a label value with a new value using regex capture groups&lt;/li&gt;
&lt;li&gt;&lt;code&gt;keep&lt;/code&gt;: Keep entries where labels match the regex (useful for filtering)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;drop&lt;/code&gt;: Drop entries where labels match the regex (useful for excluding)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hashmod&lt;/code&gt;: Set a label to the modulus of a hash of labels (useful for sharding)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labelmap&lt;/code&gt;: Copy labels to other labels based on regex matching&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labeldrop&lt;/code&gt;: Remove labels matching the regex pattern&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labelkeep&lt;/code&gt;: Keep only labels matching the regex pattern&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lowercase&lt;/code&gt;: Convert label values to lowercase&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uppercase&lt;/code&gt;: Convert label values to uppercase&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configuration-fields&#34;&gt;Configuration Fields&lt;/h3&gt;
&lt;p&gt;Each relabel configuration supports these fields (all fields are optional except for &lt;code&gt;action&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;source_labels&lt;/code&gt;: List of label names to use as input for the action&lt;/li&gt;
&lt;li&gt;&lt;code&gt;separator&lt;/code&gt;: String to join source label values (default: &amp;ldquo;;&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;target_label&lt;/code&gt;: Label to modify (required for replace and hashmod actions)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;regex&lt;/code&gt;: Regular expression to match against (defaults to &amp;ldquo;(.&#43;)&amp;rdquo; for most actions)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;replacement&lt;/code&gt;: Replacement pattern for matched regex, supports ${1}, ${2}, etc. for capture groups&lt;/li&gt;
&lt;li&gt;&lt;code&gt;modulus&lt;/code&gt;: Modulus for hashmod action&lt;/li&gt;
&lt;li&gt;&lt;code&gt;action&lt;/code&gt;: One of the supported actions listed above&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;important-notes&#34;&gt;Important Notes&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Relabeling is applied after merging extra labels and dropping labels specified by &lt;code&gt;DROP_LABELS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If all labels are removed after relabeling, the log entry will be dropped entirely.&lt;/li&gt;
&lt;li&gt;The relabeling configuration follows the same format as Prometheus&amp;rsquo;s relabel_configs, making it familiar for users of Prometheus.&lt;/li&gt;
&lt;li&gt;Relabeling rules are processed in order, and each rule can affect the input of subsequent rules.&lt;/li&gt;
&lt;li&gt;Regular expressions in the &lt;code&gt;regex&lt;/code&gt; field support full RE2 syntax.&lt;/li&gt;
&lt;li&gt;For the &lt;code&gt;replace&lt;/code&gt; action, if the &lt;code&gt;regex&lt;/code&gt; doesn&amp;rsquo;t match, the target label remains unchanged.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For more details about how relabeling works and advanced use cases, refer to the &lt;a href=&#34;/blog/2022/03/21/how-relabeling-in-prometheus-works/&#34;&gt;Prometheus relabeling blog post&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;h3 id=&#34;promtail-labels&#34;&gt;Promtail labels&lt;/h3&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;This section is relevant if running Promtail between lambda-promtail and the end Loki deployment and was used to circumvent &lt;code&gt;out of order&lt;/code&gt; problems prior to the v2.4 Loki release which removed the ordering constraint.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;As stated earlier, this workflow moves the worst case stream cardinality from &lt;code&gt;number_of_log_streams&lt;/code&gt; -&amp;gt; &lt;code&gt;number_of_log_groups&lt;/code&gt; * &lt;code&gt;number_of_promtails&lt;/code&gt;. For this reason, each Promtail must have a unique label attached to logs it processes (ideally via something like &lt;code&gt;--client.external-labels=promtail=${HOSTNAME}&lt;/code&gt;) and it&amp;rsquo;s advised to run a small number of Promtails behind a load balancer according to your throughput and redundancy needs.&lt;/p&gt;
&lt;p&gt;This trade-off is very effective when you have a large number of log streams but want to aggregate them by the log group. This is very common in AWS Lambda, where log groups are the &amp;ldquo;application&amp;rdquo; and log streams are the individual application containers which are spun up and down at a whim, possibly just for a single function invocation.&lt;/p&gt;
&lt;h3 id=&#34;data-persistence&#34;&gt;Data Persistence&lt;/h3&gt;
&lt;h4 id=&#34;availability&#34;&gt;Availability&lt;/h4&gt;
&lt;p&gt;For availability concerns, run a set of Promtails behind a load balancer.&lt;/p&gt;
&lt;h4 id=&#34;batching&#34;&gt;Batching&lt;/h4&gt;
&lt;p&gt;Relevant if lambda-promtail is configured to write to Promtail. Since Promtail batches writes to Loki for performance, it&amp;rsquo;s possible that Promtail will receive a log, issue a successful &lt;code&gt;204&lt;/code&gt; http status code for the write, then be killed at a later time before it writes upstream to Loki. This should be rare, but is a downside this workflow has.&lt;/p&gt;
&lt;p&gt;This lambda will flush logs when the batch size hits the default value of &lt;code&gt;131072&lt;/code&gt; (128KB), this can be changed with &lt;code&gt;BATCH_SIZE&lt;/code&gt; environment variable, which is set to the number of bytes to use.&lt;/p&gt;
&lt;h3 id=&#34;templatingdeployment&#34;&gt;Templating/Deployment&lt;/h3&gt;
&lt;p&gt;The current CloudFormation template is rudimentary. If you need to add vpc configs, extra log groups to monitor, subnet declarations, etc, you&amp;rsquo;ll need to edit the template manually. If you need to subscribe to more than one Cloudwatch Log Group you&amp;rsquo;ll also need to copy paste that section of the template for each group.&lt;/p&gt;
&lt;p&gt;The Terraform file is a bit more fleshed out, and can be configured to take in an array of log group and bucket names, as well as vpc configuration.&lt;/p&gt;
&lt;p&gt;The provided Terraform and CloudFormation files are meant to cover the default use case, and more complex deployments will likely require some modification and extension of the provided files.&lt;/p&gt;
&lt;h2 id=&#34;example-promtail-config&#34;&gt;Example Promtail Config&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;This should be run in conjunction with a Promtail-specific label attached, ideally via a flag argument like &lt;code&gt;--client.external-labels=promtail=${HOSTNAME}&lt;/code&gt;. It will receive writes via the push-api on ports &lt;code&gt;3500&lt;/code&gt; (http) and &lt;code&gt;3600&lt;/code&gt; (grpc).&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://ip_or_hostname_where_Loki_run:3100/loki/api/v1/push

scrape_configs:
  - job_name: push1
    loki_push_api:
      server:
        http_listen_port: 3500
        grpc_listen_port: 3600
      labels:
        # Adds a label on all streams indicating it was processed by the lambda-promtail workflow.
        promtail: &amp;#39;lambda-promtail&amp;#39;
    relabel_configs:
      - source_labels: [&amp;#39;__aws_log_type&amp;#39;]
        target_label: &amp;#39;log_type&amp;#39;
      # Maps the cloudwatch log group into a label called `log_group` for use in Loki.
      - source_labels: [&amp;#39;__aws_cloudwatch_log_group&amp;#39;]
        target_label: &amp;#39;log_group&amp;#39;
      # Maps the loadbalancer name into a label called `loadbalancer_name` for use in Loki.
      - source_labels: [&amp;#39;__aws_s3_log_lb&amp;#39;]
        target_label: &amp;#39;loadbalancer_name&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;multiple-promtail-deployment&#34;&gt;Multiple Promtail Deployment&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer: The following section is only relevant for older versions of Loki that cannot accept out of order logs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;However, these may only be active for a very short while. This creates a problem for combining these short-lived log streams in Loki because timestamps may not strictly increase across multiple log streams. The other obvious route is creating labels based on log streams, which is also undesirable because it leads to cardinality problems via many low-throughput log streams.&lt;/p&gt;
&lt;p&gt;Instead we can pipeline Cloudwatch logs to a set of Promtails, which can mitigate these problem in two ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Using Promtail&amp;rsquo;s push api along with the &lt;code&gt;use_incoming_timestamp: false&lt;/code&gt; config, we let Promtail determine the timestamp based on when it ingests the logs, not the timestamp assigned by cloudwatch. Obviously, this means that we lose the origin timestamp because Promtail now assigns it, but this is a relatively small difference in a real time ingestion system like this.&lt;/li&gt;
&lt;li&gt;In conjunction with (1), Promtail can coalesce logs across  Cloudwatch log streams because it&amp;rsquo;s no longer susceptible to out-of-order errors when combining multiple sources (lambda invocations).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One important aspect to keep in mind when running with a set of Promtails behind a load balancer is that we&amp;rsquo;re effectively moving the cardinality problems from the  number of log streams -&amp;gt; number of Promtails. If you have not configured Loki to 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/#accept-out-of-order-writes&#34;&gt;accept out-of-order writes&lt;/a&gt;, you&amp;rsquo;ll need to assign a Promtail-specific label on each Promtail so that you don&amp;rsquo;t run into out-of-order errors when the Promtails send data for the same log groups to Loki. This can easily be done via a configuration like &lt;code&gt;--client.external-labels=promtail=${HOSTNAME}&lt;/code&gt; passed to Promtail.&lt;/p&gt;
]]></content><description>&lt;h1 id="lambda-promtail-client">Lambda Promtail client&lt;/h1>
&lt;p>Grafana Loki includes &lt;a href="https://www.terraform.io/" target="_blank" rel="noopener noreferrer">Terraform&lt;/a> and &lt;a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener noreferrer">CloudFormation&lt;/a> for shipping Cloudwatch, Cloudtrail, VPC Flow Logs and loadbalancer logs to Loki via a &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener noreferrer">lambda function&lt;/a>. This is done via &lt;a href="https://github.com/grafana/lambda-promtail" target="_blank" rel="noopener noreferrer">lambda-promtail&lt;/a> which processes cloudwatch events and propagates them to Loki (or a Promtail instance) via the push-api &lt;a href="/docs/loki/latest/send-data/promtail/configuration/#loki_push_api">scrape config&lt;/a>.&lt;/p></description></item><item><title>Logstash plugin</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/logstash/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/logstash/</guid><content><![CDATA[&lt;h1 id=&#34;logstash-plugin&#34;&gt;Logstash plugin&lt;/h1&gt;
&lt;p&gt;Grafana Loki has a &lt;a href=&#34;https://www.elastic.co/logstash&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Logstash&lt;/a&gt; output plugin called
&lt;code&gt;logstash-output-loki&lt;/code&gt; that enables shipping logs to a Loki
instance or &lt;a href=&#34;/products/cloud/&#34;&gt;Grafana Cloud&lt;/a&gt;.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;Grafana Labs does not recommend using the Logstash plugin for new deployments. Even as a mechanism for quickly testing Loki with your existing Beats/Logstash infrastructure we highly discourage the use of this plugin.&lt;/p&gt;
&lt;p&gt;Our experience over the years has found numerous significant challenges using Logstash and this plugin:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is very difficult to configure labels correctly.  Conceptually Elasticsearch is a very different database from Loki and users almost always end up sending too many high cardinality labels to Loki, which makes getting started with Loki unnecessarily complicated and confusing vs. using other clients.&lt;/li&gt;
&lt;li&gt;Logstash and the upstream Beats components implement backoff and flow control which we&amp;rsquo;ve found hard to observe, leading to ingestion delays into Loki which are extremely difficult to address.&lt;/li&gt;
&lt;li&gt;We at Grafana Labs have no expertise at configuring Logstash or understanding of its configuration language, so we cannot provide support for it.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s very hard to troubleshoot and debug. Our experience has shown that in nearly every case where it was assumed this would be the fast path to getting logs to Loki, that was not the case and it ended up taking far longer than anticipated.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please strongly consider using any alternative mechanism to sending logs to Loki. We recommend using &lt;a href=&#34;/docs/loki/latest/send-data/alloy/&#34;&gt;Grafana Alloy&lt;/a&gt;.  This is the tool we build and where we can offer the best experience and most support.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;h3 id=&#34;local&#34;&gt;Local&lt;/h3&gt;
&lt;p&gt;If you need to install the Logstash output plugin manually you can do simply so by using the command below:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;$ bin/logstash-plugin install logstash-output-loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will download the latest gem for the output plugin and install it in logstash.&lt;/p&gt;
&lt;h3 id=&#34;docker&#34;&gt;Docker&lt;/h3&gt;
&lt;p&gt;We also provide a docker image on &lt;a href=&#34;https://hub.docker.com/r/grafana/logstash-output-loki&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;docker hub&lt;/a&gt;. The image contains logstash and the Loki output plugin
already pre-installed.&lt;/p&gt;
&lt;p&gt;For example if you want to run logstash in docker with the &lt;code&gt;loki.conf&lt;/code&gt; as pipeline configuration you can use the command bellow :&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;docker run -v `pwd`/loki-test.conf:/home/logstash/ --rm grafana/logstash-output-loki:1.0.1 -f loki-test.conf&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;kubernetes&#34;&gt;Kubernetes&lt;/h3&gt;
&lt;p&gt;We also provide default helm values for scraping logs with Filebeat and forward them to Loki with logstash in our &lt;code&gt;loki-stack&lt;/code&gt; umbrella chart.
You can switch to logstash by using the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm upgrade --install loki loki/loki-stack \
    --set filebeat.enabled=true,logstash.enabled=true,promtail.enabled=false \
    --set loki.fullnameOverride=loki,logstash.fullnameOverride=logstash-loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will automatically scrape all pods logs in the cluster and send them to Loki with Kubernetes metadata attached as labels.
You can use the &lt;a href=&#34;https://github.com/grafana/helm-charts/blob/main/charts/loki-stack/values.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;values.yaml&lt;/code&gt;&lt;/a&gt; file as a starting point for your own configuration.&lt;/p&gt;
&lt;h2 id=&#34;usage-and-configuration&#34;&gt;Usage and Configuration&lt;/h2&gt;
&lt;p&gt;To configure Logstash to forward logs to Loki, simply add the &lt;code&gt;loki&lt;/code&gt; output to your &lt;a href=&#34;https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Logstash configuration file&lt;/a&gt; as documented below :&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;output {
  loki {
    [url =&amp;gt; &amp;#34;&amp;#34; | default = none | required=true]

    [tenant_id =&amp;gt; string | default = nil | required=false]

    [message_field =&amp;gt; string | default = &amp;#34;message&amp;#34; | required=false]

    [include_fields =&amp;gt; array | default = [] | required=false]

    [metadata_fields =&amp;gt; array | default = [] | required=false]

    [batch_wait =&amp;gt; number | default = 1(s) | required=false]

    [batch_size =&amp;gt; number | default = 102400(bytes) | required=false]

    [min_delay =&amp;gt; number | default = 1(s) | required=false]

    [max_delay =&amp;gt; number | default = 300(s) | required=false]

    [retries =&amp;gt; number | default = 10 | required=false]

    [username =&amp;gt; string | default = nil | required=false]

    [password =&amp;gt; secret | default = nil | required=false]

    [cert =&amp;gt; path | default = nil | required=false]

    [key =&amp;gt; path | default = nil| required=false]

    [ca_cert =&amp;gt; path | default = nil | required=false]

    [insecure_skip_verify =&amp;gt; boolean | default = false | required=false]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By default Loki will create entry from event fields it receives.
A logstash event as shown below.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;{
  &amp;#34;@timestamp&amp;#34; =&amp;gt; 2017-04-26T19:33:39.257Z,
  &amp;#34;src&amp;#34;        =&amp;gt; &amp;#34;localhost&amp;#34;,
  &amp;#34;@version&amp;#34;   =&amp;gt; &amp;#34;1&amp;#34;,
  &amp;#34;host&amp;#34;       =&amp;gt; &amp;#34;localhost.localdomain&amp;#34;,
  &amp;#34;pid&amp;#34;        =&amp;gt; &amp;#34;1&amp;#34;,
  &amp;#34;message&amp;#34;    =&amp;gt; &amp;#34;Apr 26 12:20:02 localhost systemd[1]: Starting system activity accounting tool...&amp;#34;,
  &amp;#34;type&amp;#34;       =&amp;gt; &amp;#34;stdin&amp;#34;,
  &amp;#34;prog&amp;#34;       =&amp;gt; &amp;#34;systemd&amp;#34;,
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Contains a &lt;code&gt;message&lt;/code&gt; and &lt;code&gt;@timestamp&lt;/code&gt; fields, which are respectively used to form the Loki entry log line and timestamp.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use a different property for the log line by using the configuration property &lt;a href=&#34;#message_field&#34;&gt;&lt;code&gt;message_field&lt;/code&gt;&lt;/a&gt;. If you also need to change the timestamp value use the Logstash &lt;code&gt;date&lt;/code&gt; filter to change the &lt;code&gt;@timestamp&lt;/code&gt; field.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;All other fields (except nested fields) will form the label set (key value pairs) attached to the log line. &lt;a href=&#34;/blog/2020/04/21/how-labels-in-loki-can-make-log-queries-faster-and-easier/&#34;&gt;This means you&amp;rsquo;re responsible for mutating and dropping high cardinality labels&lt;/a&gt; such as client IPs.
You can usually do so by using a &lt;a href=&#34;https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;mutate&lt;/code&gt;&lt;/a&gt; filter.&lt;/p&gt;
&lt;p&gt;For example the configuration below :&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;input {
  ...
}

filter {
  mutate {
    add_field =&amp;gt; {
      &amp;#34;cluster&amp;#34; =&amp;gt; &amp;#34;us-central1&amp;#34;
      &amp;#34;job&amp;#34; =&amp;gt; &amp;#34;logstash&amp;#34;
    }
    replace =&amp;gt; { &amp;#34;type&amp;#34; =&amp;gt; &amp;#34;stream&amp;#34;}
    remove_field =&amp;gt; [&amp;#34;src&amp;#34;]
  }
}
output {
  loki {
    url =&amp;gt; &amp;#34;http://myloki.domain:3100/loki/api/v1/push&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Will add &lt;code&gt;cluster&lt;/code&gt; and &lt;code&gt;job&lt;/code&gt; static labels, remove &lt;code&gt;src&lt;/code&gt; fields and replace &lt;code&gt;type&lt;/code&gt; to be named &lt;code&gt;stream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want to include nested fields or metadata fields (starting with &lt;code&gt;@&lt;/code&gt;) you need to rename them.&lt;/p&gt;
&lt;p&gt;For example when using Filebeat with the &lt;a href=&#34;https://www.elastic.co/guide/en/beats/filebeat/current/add-kubernetes-metadata.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;add_kubernetes_metadata&lt;/code&gt;&lt;/a&gt; processor, it will attach Kubernetes metadata to your events like below:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;kubernetes&amp;#34; : {
    &amp;#34;labels&amp;#34; : {
      &amp;#34;app&amp;#34; : &amp;#34;MY-APP&amp;#34;,
      &amp;#34;pod-template-hash&amp;#34; : &amp;#34;959f54cd&amp;#34;,
      &amp;#34;serving&amp;#34; : &amp;#34;true&amp;#34;,
      &amp;#34;version&amp;#34; : &amp;#34;1.0&amp;#34;,
      &amp;#34;visualize&amp;#34; : &amp;#34;true&amp;#34;
    },
    &amp;#34;pod&amp;#34; : {
      &amp;#34;uid&amp;#34; : &amp;#34;e20173cb-3c5f-11ea-836e-02c1ee65b375&amp;#34;,
      &amp;#34;name&amp;#34; : &amp;#34;MY-APP-959f54cd-lhd5p&amp;#34;
    },
    &amp;#34;node&amp;#34; : {
      &amp;#34;name&amp;#34; : &amp;#34;ip-xxx-xx-xx-xxx.ec2.internal&amp;#34;
    },
    &amp;#34;container&amp;#34; : {
      &amp;#34;name&amp;#34; : &amp;#34;istio&amp;#34;
    },
    &amp;#34;namespace&amp;#34; : &amp;#34;production&amp;#34;,
    &amp;#34;replicaset&amp;#34; : {
      &amp;#34;name&amp;#34; : &amp;#34;MY-APP-959f54cd&amp;#34;
    }
  },
  &amp;#34;message&amp;#34;: &amp;#34;Failed to parse configuration&amp;#34;,
  &amp;#34;@timestamp&amp;#34;: &amp;#34;2017-04-26T19:33:39.257Z&amp;#34;,
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The filter below show you how to extract those Kubernetes fields into labels (&lt;code&gt;container_name&lt;/code&gt;,&lt;code&gt;namespace&lt;/code&gt;,&lt;code&gt;pod&lt;/code&gt; and &lt;code&gt;host&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;filter {
  if [kubernetes] {
    mutate {
      add_field =&amp;gt; {
        &amp;#34;container_name&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][container][name]}&amp;#34;
        &amp;#34;namespace&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][namespace]}&amp;#34;
        &amp;#34;pod&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][pod][name]}&amp;#34;
      }
      replace =&amp;gt; { &amp;#34;host&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][node][name]}&amp;#34;}
    }
  }
  mutate {
    remove_field =&amp;gt; [&amp;#34;tags&amp;#34;]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;version-notes&#34;&gt;Version Notes&lt;/h3&gt;
&lt;p&gt;Important notes regarding versions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version 1.1.0 and greater of this plugin you can also specify a list of labels to allow list via the &lt;code&gt;include_fields&lt;/code&gt; configuration.&lt;/li&gt;
&lt;li&gt;Version 1.2.0 and greater of this plugin you can also specify structured metadata via the &lt;code&gt;metadata_fields&lt;/code&gt; configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configuration-properties&#34;&gt;Configuration Properties&lt;/h3&gt;
&lt;h4 id=&#34;url&#34;&gt;url&lt;/h4&gt;
&lt;p&gt;The url of the Loki server to send logs to.
When sending data the push path need to also be provided e.g. &lt;code&gt;http://localhost:3100/loki/api/v1/push&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want to send to &lt;a href=&#34;/products/cloud/&#34;&gt;GrafanaCloud&lt;/a&gt; you would use &lt;code&gt;https://logs-prod-us-central1.grafana.net/loki/api/v1/push&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;username--password&#34;&gt;username / password&lt;/h4&gt;
&lt;p&gt;Specify a username and password if the Loki server requires basic authentication.
If using the &lt;a href=&#34;/products/cloud/&#34;&gt;GrafanaLab&amp;rsquo;s hosted Loki&lt;/a&gt;, the username needs to be set to your instance/user id and the password should be a Grafana.com api key.&lt;/p&gt;
&lt;h4 id=&#34;message_field&#34;&gt;message_field&lt;/h4&gt;
&lt;p&gt;Message field to use for log lines. You can use logstash key accessor language to grab nested property, for example : &lt;code&gt;[log][message]&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;include_fields&#34;&gt;include_fields&lt;/h4&gt;
&lt;p&gt;An array of fields which will be mapped to labels and sent to Loki, when this list is configured &lt;strong&gt;only&lt;/strong&gt; these fields will be sent, all other fields will be ignored.&lt;/p&gt;
&lt;h4 id=&#34;metadata_fields&#34;&gt;metadata_fields&lt;/h4&gt;
&lt;p&gt;An array of fields which will be mapped to &lt;a href=&#34;../../get-started/labels/structured-metadata/&#34;&gt;structured metadata&lt;/a&gt; and sent to Loki for each log line&lt;/p&gt;
&lt;h4 id=&#34;batch_wait&#34;&gt;batch_wait&lt;/h4&gt;
&lt;p&gt;Interval in seconds to wait before pushing a batch of records to Loki. This means even if the &lt;a href=&#34;#batch_size&#34;&gt;batch size&lt;/a&gt; is not reached after &lt;code&gt;batch_wait&lt;/code&gt; a partial batch will be sent, this is to ensure freshness of the data.&lt;/p&gt;
&lt;h4 id=&#34;batch_size&#34;&gt;batch_size&lt;/h4&gt;
&lt;p&gt;Maximum batch size to accrue before pushing to Loki. Defaults to 102400 bytes&lt;/p&gt;
&lt;h4 id=&#34;backoff-config&#34;&gt;Backoff config&lt;/h4&gt;
&lt;h5 id=&#34;min_delay--11s&#34;&gt;min_delay =&amp;gt; 1(1s)&lt;/h5&gt;
&lt;p&gt;Initial backoff time between retries&lt;/p&gt;
&lt;h5 id=&#34;max_delay--3005m&#34;&gt;max_delay =&amp;gt; 300(5m)&lt;/h5&gt;
&lt;p&gt;Maximum backoff time between retries&lt;/p&gt;
&lt;h5 id=&#34;retries--10&#34;&gt;retries =&amp;gt; 10&lt;/h5&gt;
&lt;p&gt;Maximum number of retries to do. Setting it to &lt;code&gt;0&lt;/code&gt; will retry indefinitely.&lt;/p&gt;
&lt;h4 id=&#34;tenant_id&#34;&gt;tenant_id&lt;/h4&gt;
&lt;p&gt;Loki is a multi-tenant log storage platform and all requests sent must include a tenant.  For some installations the tenant will be set automatically by an authenticating proxy.  Otherwise you can define a tenant to be passed through.  The tenant can be any string value.&lt;/p&gt;
&lt;h4 id=&#34;client-certificate-verification&#34;&gt;client certificate verification&lt;/h4&gt;
&lt;p&gt;Specify a pair of client certificate and private key with &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; if a reverse proxy with client certificate verification is configured in front of Loki. &lt;code&gt;ca_cert&lt;/code&gt; can also be specified if the server uses custom certificate authority.&lt;/p&gt;
&lt;h4 id=&#34;insecure_skip_verify&#34;&gt;insecure_skip_verify&lt;/h4&gt;
&lt;p&gt;A flag to disable server certificate verification. By default it is set to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;full-configuration-example&#34;&gt;Full configuration example&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;conf&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-conf&#34;&gt;input {
  beats {
    port =&amp;gt; 5044
  }
}

filter {
  if [kubernetes] {
    mutate {
      add_field =&amp;gt; {
        &amp;#34;container_name&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][container][name]}&amp;#34;
        &amp;#34;namespace&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][namespace]}&amp;#34;
        &amp;#34;pod&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][pod][name]}&amp;#34;
      }
      replace =&amp;gt; { &amp;#34;host&amp;#34; =&amp;gt; &amp;#34;%{[kubernetes][node][name]}&amp;#34;}
    }
  }
  mutate {
    remove_field =&amp;gt; [&amp;#34;tags&amp;#34;]  # Note: with include_fields defined below this wouldn&amp;#39;t be necessary
  }
}

output {
  loki {
    url =&amp;gt; &amp;#34;https://logs-prod-us-central1.grafana.net/loki/api/v1/push&amp;#34;
    username =&amp;gt; &amp;#34;3241&amp;#34;
    password =&amp;gt; &amp;#34;REDACTED&amp;#34;
    batch_size =&amp;gt; 112640 #112.64 kilobytes
    retries =&amp;gt; 5
    min_delay =&amp;gt; 3
    max_delay =&amp;gt; 500
    message_field =&amp;gt; &amp;#34;message&amp;#34;
    include_fields =&amp;gt; [&amp;#34;container_name&amp;#34;,&amp;#34;namespace&amp;#34;,&amp;#34;pod&amp;#34;,&amp;#34;host&amp;#34;]
    metadata_fields =&amp;gt; [&amp;#34;pod&amp;#34;]
  }
  # stdout { codec =&amp;gt; rubydebug }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="logstash-plugin">Logstash plugin&lt;/h1>
&lt;p>Grafana Loki has a &lt;a href="https://www.elastic.co/logstash" target="_blank" rel="noopener noreferrer">Logstash&lt;/a> output plugin called
&lt;code>logstash-output-loki&lt;/code> that enables shipping logs to a Loki
instance or &lt;a href="/products/cloud/">Grafana Cloud&lt;/a>.&lt;/p>
&lt;div class="admonition admonition-warning">&lt;blockquote>&lt;p class="title text-uppercase">Warning&lt;/p>&lt;p>Grafana Labs does not recommend using the Logstash plugin for new deployments. Even as a mechanism for quickly testing Loki with your existing Beats/Logstash infrastructure we highly discourage the use of this plugin.&lt;/p></description></item><item><title>Using k6 for load testing</title><link>https://grafana.com/docs/loki/v3.7.x/send-data/k6/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/send-data/k6/</guid><content><![CDATA[&lt;h1 id=&#34;using-k6-for-load-testing&#34;&gt;Using k6 for load testing&lt;/h1&gt;
&lt;p&gt;Grafana &lt;a href=&#34;/oss/k6/&#34;&gt;k6&lt;/a&gt; is a modern load-testing tool.
Its clean and approachable scripting &lt;a href=&#34;/docs/k6/latest/javascript-api/&#34;&gt;API&lt;/a&gt;
works locally or in the cloud.
Its configuration makes it flexible.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/grafana/xk6-loki&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;xk6-loki extension&lt;/a&gt; permits pushing logs to and querying logs from a Loki instance.
It acts as a Loki client, simulating real-world load to test the scalability,
reliability, and performance of your Loki installation.&lt;/p&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;p&gt;k6 is written in Golang. &lt;a href=&#34;https://go.dev/doc/install&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Download and install&lt;/a&gt; a Go environment.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;xk6-loki&lt;/code&gt; is an extension to the k6 binary.
Build a custom k6 binary that includes the &lt;code&gt;xk6-loki&lt;/code&gt; extension.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install the &lt;code&gt;xk6&lt;/code&gt; extension bundler:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;go install go.k6.io/xk6/cmd/xk6@latest&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check out the &lt;code&gt;grafana/xk6-loki&lt;/code&gt; repository:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;git clone https://github.com/grafana/xk6-loki
cd xk6-loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build k6 with the extension:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;make k6&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;Use the custom-built k6 binary in the same way as a non-custom k6 binary:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;./k6 run test.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;test.js&lt;/code&gt; is a Javascript load test.
Refer to the &lt;a href=&#34;/docs/k6/latest/&#34;&gt;k6 documentation&lt;/a&gt; to get started.&lt;/p&gt;
&lt;h3 id=&#34;scripting-api&#34;&gt;Scripting API&lt;/h3&gt;
&lt;p&gt;The custom-built k6 binary provides a Javascript &lt;code&gt;loki&lt;/code&gt; module.&lt;/p&gt;
&lt;p&gt;Your Javascript load test imports the module:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;import loki from &amp;#39;k6/x/loki&amp;#39;;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Classes of this module are:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;class&lt;/th&gt;
              &lt;th&gt;description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;Config&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;configuration for the &lt;code&gt;Client&lt;/code&gt; class&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;Client&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;client for writing and reading logs from Loki&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;p&gt;&lt;code&gt;Config&lt;/code&gt; and &lt;code&gt;Client&lt;/code&gt; must be called on the k6 init context (see
&lt;a href=&#34;/docs/k6/latest/using-k6/test-lifecycle/&#34;&gt;Test life cycle&lt;/a&gt;) outside of the
default function so the client is only configured once and shared between all
VU iterations.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Client&lt;/code&gt; class exposes the following instance methods:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;method&lt;/th&gt;
              &lt;th&gt;description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;push()&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;shortcut for &lt;code&gt;pushParameterized(5, 800*1024, 1024*1024)&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;pushParameterized(streams, minSize, maxSize)&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;execute push request (
    &lt;a href=&#34;/docs/loki/v3.7.x/reference/loki-http-api/#ingest-logs&#34;&gt;POST /loki/api/v1/push&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;instantQuery(query, limit)&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;execute instant query  (
    &lt;a href=&#34;/docs/loki/v3.7.x/reference/loki-http-api/#query-logs-at-a-single-point-in-time&#34;&gt;GET /loki/api/v1/query&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;client.rangeQuery(query, duration, limit)&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;execute range query  (
    &lt;a href=&#34;/docs/loki/v3.7.x/reference/loki-http-api/#query-logs-within-a-range-of-time&#34;&gt;GET /loki/api/v1/query_range&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;client.labelsQuery(duration)&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;execute labels query  (
    &lt;a href=&#34;/docs/loki/v3.7.x/reference/loki-http-api/#query-labels&#34;&gt;GET /loki/api/v1/labels&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;client.labelValuesQuery(label, duration)&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;execute label values query  (
    &lt;a href=&#34;/docs/loki/v3.7.x/reference/loki-http-api/#query-label-values&#34;&gt;GET /loki/api/v1/label/&amp;lt;name&amp;gt;/values&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;client.seriesQuery(matchers, duration)&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;execute series query  (
    &lt;a href=&#34;/docs/loki/v3.7.x/reference/loki-http-api/#query-streams&#34;&gt;GET /loki/api/v1/series&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;p&gt;&lt;strong&gt;Javascript load test example:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;import loki from &amp;#39;k6/x/loki&amp;#39;;

const timeout = 5000; // ms
const conf = loki.Config(&amp;#34;http://localhost:3100&amp;#34;, timeout);
const client = loki.Client(conf);

export default () =&amp;gt; {
   client.pushParameterized(2, 512*1024, 1024*1024);
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Refer to
&lt;a href=&#34;https://github.com/grafana/xk6-loki#javascript-api&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;grafana/xk6-loki&lt;/a&gt;
for the complete &lt;code&gt;k6/x/loki&lt;/code&gt; module API reference.&lt;/p&gt;
]]></content><description>&lt;h1 id="using-k6-for-load-testing">Using k6 for load testing&lt;/h1>
&lt;p>Grafana &lt;a href="/oss/k6/">k6&lt;/a> is a modern load-testing tool.
Its clean and approachable scripting &lt;a href="/docs/k6/latest/javascript-api/">API&lt;/a>
works locally or in the cloud.
Its configuration makes it flexible.&lt;/p></description></item></channel></rss>