<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Clients on Grafana Labs</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/</link><description>Recent content in Clients on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/enterprise-logs/v1.9.x/loki/clients/index.xml" rel="self" type="application/rss+xml"/><item><title>Promtail</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/promtail/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/promtail/</guid><content><![CDATA[&lt;h1 id=&#34;promtail&#34;&gt;Promtail&lt;/h1&gt;
&lt;p&gt;Promtail is an agent which ships the contents of local logs to a private Grafana Loki
instance or &lt;a href=&#34;/oss/loki&#34;&gt;Grafana Cloud&lt;/a&gt;. It is usually
deployed to every machine that has applications needed to be monitored.&lt;/p&gt;
&lt;p&gt;It primarily:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Discovers targets&lt;/li&gt;
&lt;li&gt;Attaches labels to log streams&lt;/li&gt;
&lt;li&gt;Pushes them to the Loki instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently, Promtail can tail logs from two sources: local log files and the
systemd journal (on AMD64 machines only).&lt;/p&gt;
&lt;h2 id=&#34;log-file-discovery&#34;&gt;Log file discovery&lt;/h2&gt;
&lt;p&gt;Before Promtail can ship any data from log files to Loki, it needs to find out
information about its environment. Specifically, this means discovering
applications emitting log lines to files that need to be monitored.&lt;/p&gt;
&lt;p&gt;Promtail borrows the same
&lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;service discovery mechanism from Prometheus&lt;/a&gt;,
although it currently only supports &lt;code&gt;static&lt;/code&gt; and &lt;code&gt;kubernetes&lt;/code&gt; service
discovery. This limitation is due to the fact that Promtail is deployed as a
daemon to every local machine and, as such, does not discover label from other
machines. &lt;code&gt;kubernetes&lt;/code&gt; service discovery fetches required labels from the
Kubernetes API server while &lt;code&gt;static&lt;/code&gt; usually covers all other use cases.&lt;/p&gt;
&lt;p&gt;Just like Prometheus, &lt;code&gt;promtail&lt;/code&gt; is configured using a &lt;code&gt;scrape_configs&lt;/code&gt; stanza.
&lt;code&gt;relabel_configs&lt;/code&gt; allows for fine-grained control of what to ingest, what to
drop, and the final metadata to attach to the log line. Refer to the docs for
&lt;a href=&#34;configuration/&#34;&gt;configuring Promtail&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;loki-push-api&#34;&gt;Loki Push API&lt;/h2&gt;
&lt;p&gt;Promtail can also be configured to receive logs from another Promtail or any Loki client by exposing the &lt;a href=&#34;../../api#post-lokiapiv1push&#34;&gt;Loki Push API&lt;/a&gt; with the &lt;a href=&#34;configuration#loki_push_api_config&#34;&gt;loki_push_api&lt;/a&gt; scrape config.&lt;/p&gt;
&lt;p&gt;There are a few instances where this might be helpful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;complex network infrastructures where many machines having egress is not desirable.&lt;/li&gt;
&lt;li&gt;using the Docker Logging Driver and wanting to provide a complex pipeline or to extract metrics from logs.&lt;/li&gt;
&lt;li&gt;serverless setups where many ephemeral log sources want to send to Loki, sending to a Promtail instance with &lt;code&gt;use_incoming_timestamp&lt;/code&gt; == false can avoid out-of-order errors and avoid having to use high cardinality labels.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;receiving-logs-from-syslog&#34;&gt;Receiving logs From Syslog&lt;/h2&gt;
&lt;p&gt;When the &lt;a href=&#34;configuration#syslog_config&#34;&gt;Syslog Target&lt;/a&gt; is being used, logs
can be written with the syslog protocol to the configured port.&lt;/p&gt;
&lt;h2 id=&#34;aws&#34;&gt;AWS&lt;/h2&gt;
&lt;p&gt;If you need to run Promtail on Amazon Web Services EC2 instances, you can use our &lt;a href=&#34;../aws/ec2/&#34;&gt;detailed tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;labeling-and-parsing&#34;&gt;Labeling and parsing&lt;/h2&gt;
&lt;p&gt;During service discovery, metadata is determined (pod name, filename, etc.) that
may be attached to the log line as a label for easier identification when
querying logs in Loki. Through &lt;code&gt;relabel_configs&lt;/code&gt;, discovered labels can be
mutated into the desired form.&lt;/p&gt;
&lt;p&gt;To allow more sophisticated filtering afterwards, Promtail allows to set labels
not only from service discovery, but also based on the contents of each log
line. The &lt;code&gt;pipeline_stages&lt;/code&gt; can be used to add or update labels, correct the
timestamp, or re-write log lines entirely. Refer to the documentation for
&lt;a href=&#34;pipelines/&#34;&gt;pipelines&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;shipping&#34;&gt;Shipping&lt;/h2&gt;
&lt;p&gt;Once Promtail has a set of targets (i.e., things to read from, like files) and
all labels are set correctly, it will start tailing (continuously reading) the
logs from targets. Once enough data is read into memory or after a configurable
timeout, it is flushed as a single batch to Loki.&lt;/p&gt;
&lt;p&gt;As Promtail reads data from sources (files and systemd journal, if configured),
it will track the last offset it read in a positions file. By default, the
positions file is stored at &lt;code&gt;/var/log/positions.yaml&lt;/code&gt;. The positions file helps
Promtail continue reading from where it left off in the case of the Promtail
instance restarting.&lt;/p&gt;
&lt;h2 id=&#34;api&#34;&gt;API&lt;/h2&gt;
&lt;p&gt;Promtail features an embedded web server exposing a web console at &lt;code&gt;/&lt;/code&gt; and the following API endpoints:&lt;/p&gt;
&lt;h3 id=&#34;get-ready&#34;&gt;&lt;code&gt;GET /ready&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This endpoint returns 200 when Promtail is up and running, and there&amp;rsquo;s at least one working target.&lt;/p&gt;
&lt;h3 id=&#34;get-metrics&#34;&gt;&lt;code&gt;GET /metrics&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This endpoint returns Promtail metrics for Prometheus. Refer to
&lt;a href=&#34;../../operations/observability/&#34;&gt;Observing Grafana Loki&lt;/a&gt; for the list
of exported metrics.&lt;/p&gt;
&lt;h3 id=&#34;promtail-web-server-config&#34;&gt;Promtail web server config&lt;/h3&gt;
&lt;p&gt;The web server exposed by Promtail can be configured in the Promtail &lt;code&gt;.yaml&lt;/code&gt; config file:&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;server:
  http_listen_address: 127.0.0.1
  http_listen_port: 9080&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="promtail">Promtail&lt;/h1>
&lt;p>Promtail is an agent which ships the contents of local logs to a private Grafana Loki
instance or &lt;a href="/oss/loki">Grafana Cloud&lt;/a>. It is usually
deployed to every machine that has applications needed to be monitored.&lt;/p></description></item><item><title>Lambda Promtail</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/lambda-promtail/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/lambda-promtail/</guid><content><![CDATA[&lt;h1 id=&#34;lambda-promtail&#34;&gt;Lambda Promtail&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 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/loki/tree/master/tools/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;../promtail/configuration#loki_push_api_config&#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/loki/blob/main/tools/lambda-promtail/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/loki/blob/main/tools/lambda-promtail/template.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/loki/blob/main/tools/lambda-promtail/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 lables to the logs streamed by lambda-protmail.
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;Optional environment variable can be configured to add tenant id to the logs streamed by lambda-protmail.&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 are still able to clone this repo, make their own modifications to the Go code, and upload their own image to their own ECR repo if they wish.&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 code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&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&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;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;p&gt;The first few lines of &lt;code&gt;main.tf&lt;/code&gt; define the AWS region to deploy to, you are free to modify this or remove and deploy to&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&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&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#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 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 having lambda-promtail write to Promtail and using &lt;a href=&#34;/docs/loki/latest/clients/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 code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&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&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#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 you should copy/paste and modify the subscription filter section as needed for each log group:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&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&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;MainLambdaPromtailSubscriptionFilter:
  Type: AWS::Logs::SubscriptionFilter
  Properties:
    DestinationArn: !GetAtt LambdaPromtailFunction.Arn
    FilterPattern: &amp;#34;&amp;#34;
    LogGroupName: &amp;#34;/aws/lambda/some-lamda-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 tenant id add &lt;code&gt;ParameterKey=TenantID,ParameterValue=value&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To modify an already created CloudFormation stack you need to 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;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;p&gt;Note: 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;h3 id=&#34;loadbalancer-logs&#34;&gt;Loadbalancer logs&lt;/h3&gt;
&lt;p&gt;This workflow allows ingesting AWS loadbalancer logs stored on S3 to Loki.&lt;/p&gt;
&lt;h2 id=&#34;propagated-labels&#34;&gt;Propagated Labels&lt;/h2&gt;
&lt;p&gt;Incoming logs can have six special labels assigned to them which can be used in &lt;a href=&#34;../promtail/configuration/#relabel_config&#34;&gt;relabeling&lt;/a&gt; or later stages in a Promtail &lt;a href=&#34;../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 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_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;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;h3 id=&#34;promtail-labels&#34;&gt;Promtail labels&lt;/h3&gt;
&lt;p&gt;Note: 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;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 extenstion of the provided files.&lt;/p&gt;
&lt;h2 id=&#34;example-promtail-config&#34;&gt;Example Promtail Config&lt;/h2&gt;
&lt;p&gt;Note: 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;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_label: [&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;../../configuration#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">Lambda Promtail&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 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/loki/tree/master/tools/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="../promtail/configuration#loki_push_api_config">scrape config&lt;/a>.&lt;/p></description></item><item><title>AWS</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/aws/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/aws/</guid><content><![CDATA[&lt;p&gt;Sending logs from AWS services to Grafana Loki is a little different depending on what AWS service you are using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;ec2/&#34;&gt;Elastic Compute Cloud (EC2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;ecs/&#34;&gt;Elastic Container Service (ECS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;eks/&#34;&gt;Elastic Kubernetes Service (EKS)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;p>Sending logs from AWS services to Grafana Loki is a little different depending on what AWS service you are using:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="ec2/">Elastic Compute Cloud (EC2)&lt;/a>&lt;/li>
&lt;li>&lt;a href="ecs/">Elastic Container Service (ECS)&lt;/a>&lt;/li>
&lt;li>&lt;a href="eks/">Elastic Kubernetes Service (EKS)&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Docker driver</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/docker-driver/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/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 &lt;a href=&#34;/oss/loki&#34;&gt;Grafana Cloud&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Docker plugins are not yet 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;p&gt;Documentation on configuring the Loki Docker Driver can be found on the
&lt;a href=&#34;./configuration&#34;&gt;configuration page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have any questions or issues using the Docker plugin feel free to open an issue in this &lt;a href=&#34;https://github.com/grafana/loki/issues&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;installing&#34;&gt;Installing&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:&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:latest --alias loki --grant-all-permissions&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&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
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 the plugin is installed it can be &lt;a href=&#34;./configuration&#34;&gt;configured&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;upgrading&#34;&gt;Upgrading&lt;/h2&gt;
&lt;p&gt;The upgrade process involves disabling the existing plugin, upgrading, 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:latest --grant-all-permissions
docker plugin enable loki
systemctl restart docker&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;uninstalling&#34;&gt;Uninstalling&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;h1 id=&#34;know-issues&#34;&gt;Know Issues&lt;/h1&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 drive 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;Use Promtail&amp;rsquo;s &lt;a href=&#34;../promtail/configuration/#docker&#34;&gt;Docker target&lt;/a&gt; or &lt;a href=&#34;../promtail/configuration/#docker_sd_config&#34;&gt;Docker service discovery&lt;/a&gt; to avoid this issue.&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 &lt;a href="/oss/loki">Grafana Cloud&lt;/a>.&lt;/p></description></item><item><title>Fluent Bit</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/fluentbit/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/fluentbit/</guid><content><![CDATA[&lt;h1 id=&#34;fluent-bit-loki-output&#34;&gt;Fluent Bit Loki Output&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 and lightweight logs and metrics processor and forwarder that can be configured with the &lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/outputs/loki&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Grafana Loki output plugin&lt;/a&gt; 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;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;h3 id=&#34;docker&#34;&gt;Docker&lt;/h3&gt;
&lt;p&gt;You can run a Fluent Bit container with Loki output plugin pre-installed using our &lt;a href=&#34;https://hub.docker.com/r/grafana/fluent-bit-plugin-loki&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Docker Hub&lt;/a&gt; image:&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 /var/log:/var/log \
    -e LOG_PATH=&amp;#34;/var/log/*.log&amp;#34; -e LOKI_URL=&amp;#34;http://localhost:3100/loki/api/v1/push&amp;#34; \
    grafana/fluent-bit-plugin-loki:latest&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;You can run Fluent Bit as a &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Daemonset&lt;/a&gt; to collect all your Kubernetes workload logs.&lt;/p&gt;
&lt;p&gt;To do so you can use our &lt;a href=&#34;https://github.com/grafana/helm-charts/tree/main/charts/fluent-bit&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Fluent Bit helm chart&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;helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm upgrade --install fluent-bit grafana/fluent-bit \
    --set loki.serviceName=loki.svc.cluster.local&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By default it will collect all containers logs and extract labels from Kubernetes API (&lt;code&gt;container_name&lt;/code&gt;, &lt;code&gt;namespace&lt;/code&gt;, etc..).&lt;/p&gt;
&lt;p&gt;Alternatively you can install the Loki and Fluent Bit all together using:&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-stack grafana/loki-stack \
    --set fluent-bit.enabled=true,promtail.enabled=false&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;aws-elastic-container-service-ecs&#34;&gt;AWS Elastic Container Service (ECS)&lt;/h3&gt;
&lt;p&gt;You can use fluent-bit Loki Docker image as a Firelens log router in AWS ECS.
For more information about this see our &lt;a href=&#34;../aws/ecs&#34;&gt;AWS documentation&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;local&#34;&gt;Local&lt;/h3&gt;
&lt;p&gt;First, you need to follow the &lt;a href=&#34;https://github.com/grafana/loki/blob/main/clients/cmd/fluent-bit/README.md&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;instructions&lt;/a&gt; in order to build the plugin dynamic library.&lt;/p&gt;
&lt;p&gt;The assuming you have Fluent Bit installed in your &lt;code&gt;$PATH&lt;/code&gt; you can run the plugin using:&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-bit -e /path/to/built/out_grafana_loki.so -c fluent-bit.conf&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can also adapt your plugins.conf, removing the need to change the command line 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;[PLUGINS]
    Path /path/to/built/out_grafana_loki.so&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;configuration-options&#34;&gt;Configuration Options&lt;/h2&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;Key&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;Url&lt;/td&gt;
              &lt;td&gt;Url of loki server API endpoint.&lt;/td&gt;
              &lt;td&gt;http://localhost:3100/loki/api/v1/push&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;TenantID&lt;/td&gt;
              &lt;td&gt;The tenant ID used by default to push logs to Loki. If omitted or empty it assumes Loki is running in single-tenant mode and no &lt;code&gt;X-Scope-OrgID&lt;/code&gt; header is sent.&lt;/td&gt;
              &lt;td&gt;&amp;quot;&amp;quot;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;BatchWait&lt;/td&gt;
              &lt;td&gt;Time to wait before send a log batch to Loki, full or not.&lt;/td&gt;
              &lt;td&gt;1s&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;BatchSize&lt;/td&gt;
              &lt;td&gt;Log batch size to send a log batch to Loki (unit: Bytes).&lt;/td&gt;
              &lt;td&gt;10 KiB (10 * 1024 Bytes)&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Timeout&lt;/td&gt;
              &lt;td&gt;Maximum time to wait for loki server to respond to a request.&lt;/td&gt;
              &lt;td&gt;10s&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;MinBackoff&lt;/td&gt;
              &lt;td&gt;Initial backoff time between retries.&lt;/td&gt;
              &lt;td&gt;500ms&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;MaxBackoff&lt;/td&gt;
              &lt;td&gt;Maximum backoff time between retries.&lt;/td&gt;
              &lt;td&gt;5m&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;MaxRetries&lt;/td&gt;
              &lt;td&gt;Maximum number of retries when sending batches. Setting it to &lt;code&gt;0&lt;/code&gt; will retry indefinitely.&lt;/td&gt;
              &lt;td&gt;10&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Labels&lt;/td&gt;
              &lt;td&gt;labels for API requests.&lt;/td&gt;
              &lt;td&gt;{job=&amp;ldquo;fluent-bit&amp;rdquo;}&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;LogLevel&lt;/td&gt;
              &lt;td&gt;LogLevel for plugin logger.&lt;/td&gt;
              &lt;td&gt;&amp;ldquo;info&amp;rdquo;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;RemoveKeys&lt;/td&gt;
              &lt;td&gt;Specify removing keys.&lt;/td&gt;
              &lt;td&gt;none&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;AutoKubernetesLabels&lt;/td&gt;
              &lt;td&gt;If set to true, it will add all Kubernetes labels to Loki labels&lt;/td&gt;
              &lt;td&gt;false&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;LabelKeys&lt;/td&gt;
              &lt;td&gt;Comma separated list of keys to use as stream labels. All other keys will be placed into the log line. LabelKeys is deactivated when using &lt;code&gt;LabelMapPath&lt;/code&gt; label mapping configuration.&lt;/td&gt;
              &lt;td&gt;none&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;LineFormat&lt;/td&gt;
              &lt;td&gt;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;key&gt;=&lt;value&gt;.&lt;/td&gt;
              &lt;td&gt;json&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;DropSingleKey&lt;/td&gt;
              &lt;td&gt;If set to true and after extracting label_keys a record only has a single key remaining, the log line sent to Loki will just be the value of the record key.&lt;/td&gt;
              &lt;td&gt;true&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;LabelMapPath&lt;/td&gt;
              &lt;td&gt;Path to a json file defining how to transform nested records.&lt;/td&gt;
              &lt;td&gt;none&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Buffer&lt;/td&gt;
              &lt;td&gt;Enable buffering mechanism&lt;/td&gt;
              &lt;td&gt;false&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;BufferType&lt;/td&gt;
              &lt;td&gt;Specify the buffering mechanism to use (currently only dque is implemented).&lt;/td&gt;
              &lt;td&gt;dque&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;DqueDir&lt;/td&gt;
              &lt;td&gt;Path to the directory for queued logs&lt;/td&gt;
              &lt;td&gt;/tmp/flb-storage/loki&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;DqueSegmentSize&lt;/td&gt;
              &lt;td&gt;Segment size in terms of number of records per segment&lt;/td&gt;
              &lt;td&gt;500&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;DqueSync&lt;/td&gt;
              &lt;td&gt;Whether to fsync each queue change. Specify no fsync with &amp;ldquo;normal&amp;rdquo;, and fsync with &amp;ldquo;full&amp;rdquo;.&lt;/td&gt;
              &lt;td&gt;&amp;ldquo;normal&amp;rdquo;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;DqueName&lt;/td&gt;
              &lt;td&gt;Queue name, must be uniq per output&lt;/td&gt;
              &lt;td&gt;dque&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h3 id=&#34;labels&#34;&gt;Labels&lt;/h3&gt;
&lt;p&gt;Labels are used to &lt;a href=&#34;../../logql&#34;&gt;query logs&lt;/a&gt; &lt;code&gt;{container_name=&amp;quot;nginx&amp;quot;, cluster=&amp;quot;us-west1&amp;quot;}&lt;/code&gt;, they are usually metadata about the workload producing the log stream (&lt;code&gt;instance&lt;/code&gt;, &lt;code&gt;container_name&lt;/code&gt;, &lt;code&gt;region&lt;/code&gt;, &lt;code&gt;cluster&lt;/code&gt;, &lt;code&gt;level&lt;/code&gt;).  In Loki labels are indexed consequently you should be cautious when choosing them (high cardinality label values can have performance drastic impact).&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;Labels&lt;/code&gt;, &lt;code&gt;RemoveKeys&lt;/code&gt; , &lt;code&gt;LabelKeys&lt;/code&gt; and &lt;code&gt;LabelMapPath&lt;/code&gt; to how the output plugin will perform labels extraction.&lt;/p&gt;
&lt;h3 id=&#34;autokuberneteslabels&#34;&gt;AutoKubernetesLabels&lt;/h3&gt;
&lt;p&gt;If set to true, it will add all Kubernetes labels to Loki labels automatically and ignore parameters &lt;code&gt;LabelKeys&lt;/code&gt;, LabelMapPath.&lt;/p&gt;
&lt;h3 id=&#34;labelmappath&#34;&gt;LabelMapPath&lt;/h3&gt;
&lt;p&gt;When using the &lt;code&gt;Parser&lt;/code&gt; and &lt;code&gt;Filter&lt;/code&gt; plugins Fluent Bit can extract and add data to the current record/log data. While Loki labels are key value pair, record data can be nested structures.
You can pass a JSON file that defines how to extract labels from each record. Each json key from the file will be matched with the log record to find label values. Values from the configuration are used as label names.&lt;/p&gt;
&lt;p&gt;Considering the record 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;container_name&amp;#34;: &amp;#34;promtail&amp;#34;,
    &amp;#34;pod_name&amp;#34;: &amp;#34;promtail-xxx&amp;#34;,
    &amp;#34;namespace_name&amp;#34;: &amp;#34;prod&amp;#34;,
    &amp;#34;labels&amp;#34; : {
        &amp;#34;team&amp;#34;: &amp;#34;x-men&amp;#34;
    }
  },
  &amp;#34;HOSTNAME&amp;#34;: &amp;#34;docker-desktop&amp;#34;,
  &amp;#34;log&amp;#34; : &amp;#34;a log line&amp;#34;,
  &amp;#34;time&amp;#34;: &amp;#34;20190926T152206Z&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and a LabelMap file as follow :&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;container_name&amp;#34;: &amp;#34;container&amp;#34;,
    &amp;#34;pod_name&amp;#34;: &amp;#34;pod&amp;#34;,
    &amp;#34;namespace_name&amp;#34;: &amp;#34;namespace&amp;#34;,
    &amp;#34;labels&amp;#34; : {
        &amp;#34;team&amp;#34;: &amp;#34;team&amp;#34;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The labels extracted will be &lt;code&gt;{team=&amp;quot;x-men&amp;quot;, container=&amp;quot;promtail&amp;quot;, pod=&amp;quot;promtail-xxx&amp;quot;, namespace=&amp;quot;prod&amp;quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t want the &lt;code&gt;kubernetes&lt;/code&gt; and &lt;code&gt;HOSTNAME&lt;/code&gt; fields to appear in the log line you can use the &lt;code&gt;RemoveKeys&lt;/code&gt; configuration field. (e.g. &lt;code&gt;RemoveKeys kubernetes,HOSTNAME&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&#34;buffering&#34;&gt;Buffering&lt;/h3&gt;
&lt;p&gt;Buffering refers to the ability to store the records somewhere, and while they are processed and delivered, still be able to store more. The Loki output plugin can be blocked by the Loki client because of its design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the BatchSize is over the limit, the output plugin pauses receiving new records until the pending batch is successfully sent to the server&lt;/li&gt;
&lt;li&gt;If the Loki server is unreachable (retry 429s, 500s and connection-level errors), the output plugin blocks new records until the Loki server is available again, and the pending batch is successfully sent to the server or as long as the maximum number of attempts has been reached within configured back-off mechanism&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The blocking state with some of the input plugins is not acceptable, because it can have an undesirable side effect on the part that generates the logs. Fluent Bit implements a buffering mechanism that is based on parallel processing. Therefore, it cannot send logs in order. There are two ways of handling the out-of-order logs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Configure Loki to &lt;a href=&#34;../../configuration/#accept-out-of-order-writes&#34;&gt;accept out-of-order writes&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure the Loki output plugin to use the buffering mechanism based on &lt;a href=&#34;https://github.com/joncrlsn/dque&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;dque&lt;/code&gt;&lt;/a&gt;, which is compatible with the Loki server strict time ordering:&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;properties&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-properties&#34;&gt;[Output]
    Name grafana-loki
    Match *
    Url http://localhost:3100/loki/api/v1/push
    Buffer true
    DqueSegmentSize 8096
    DqueDir /tmp/flb-storage/buffer
    DqueName loki.0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configuration-examples&#34;&gt;Configuration examples&lt;/h3&gt;
&lt;p&gt;To configure the Loki output plugin add this section to fluent-bit.conf&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;properties&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-properties&#34;&gt;[Output]
    Name grafana-loki
    Match *
    Url http://localhost:3100/loki/api/v1/push
    BatchWait 1s
    BatchSize 30720
    # (30KiB)
    Labels {test=&amp;#34;fluent-bit-go&amp;#34;, lang=&amp;#34;Golang&amp;#34;}
    RemoveKeys key1,key2
    LabelKeys key3,key4
    LineFormat key_value&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;properties&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-properties&#34;&gt;[Output]
    Name grafana-loki
    Match *
    Url http://localhost:3100/loki/api/v1/push
    BatchWait 1s
    BatchSize 30720 # (30KiB)
    AutoKubernetesLabels true
    RemoveKeys key1,key2&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A full &lt;a href=&#34;https://github.com/grafana/loki/blob/master/clients/cmd/fluent-bit/fluent-bit.conf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;example configuration file&lt;/a&gt; is also available in the Loki repository.&lt;/p&gt;
&lt;h3 id=&#34;running-multiple-plugin-instances&#34;&gt;Running multiple plugin instances&lt;/h3&gt;
&lt;p&gt;You can run multiple plugin instances in the same fluent-bit process, for example if you want to push to different Loki servers or route logs into different Loki tenant IDs. To do so, add additional &lt;code&gt;[Output]&lt;/code&gt; sections.&lt;/p&gt;
]]></content><description>&lt;h1 id="fluent-bit-loki-output">Fluent Bit Loki Output&lt;/h1>
&lt;p>&lt;a href="https://fluentbit.io/" target="_blank" rel="noopener noreferrer">Fluent Bit&lt;/a> is a fast and lightweight logs and metrics processor and forwarder that can be configured with the &lt;a href="https://docs.fluentbit.io/manual/pipeline/outputs/loki" target="_blank" rel="noopener noreferrer">Grafana Loki output plugin&lt;/a> to ship logs to Loki. You can define which log files you want to collect using the &lt;a href="https://docs.fluentbit.io/manual/pipeline/inputs/tail" target="_blank" rel="noopener noreferrer">&lt;code>Tail&lt;/code>&lt;/a> or &lt;a href="https://docs.fluentbit.io/manual/pipeline/inputs/standard-input" target="_blank" rel="noopener noreferrer">&lt;code>Stdin&lt;/code>&lt;/a> data pipeline input. Additionally, Fluent Bit supports multiple &lt;code>Filter&lt;/code> and &lt;code>Parser&lt;/code> plugins (&lt;code>Kubernetes&lt;/code>, &lt;code>JSON&lt;/code>, etc.) to structure and alter log lines.&lt;/p></description></item><item><title>Fluentd</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/fluentd/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/fluentd/</guid><content><![CDATA[&lt;h1 id=&#34;fluentd-loki-output-plugin&#34;&gt;Fluentd Loki Output Plugin&lt;/h1&gt;
&lt;p&gt;Grafana Loki has a &lt;a href=&#34;https://www.fluentd.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Fluentd&lt;/a&gt; output plugin 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;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:master&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&amp;rsquo;s 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 will start an instance of Fluentd to forward 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:master
    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;p&gt;&lt;strong&gt;Note&lt;/strong&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;p&gt;In your Fluentd configuration, use &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;}
  flush_interval 10s
  flush_at_shutdown true
  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;As Kubernetes labels are a list of nested key-value pairs there is a separate option 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;Out-of-order inserts are enabled by default in Loki; refer to &lt;a href=&#34;../../configuration/#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;../api/loki/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;Specify a username and password if the Loki server requires authentication.
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;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;p&gt;The tenant field also supports placeholders, so it can 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 k8s 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;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;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 a 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;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;There are few configurations settings 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-loki-output-plugin">Fluentd Loki Output Plugin&lt;/h1>
&lt;p>Grafana Loki has a &lt;a href="https://www.fluentd.org/" target="_blank" rel="noopener noreferrer">Fluentd&lt;/a> output plugin 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>Logstash</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/logstash/</link><pubDate>Tue, 16 Jul 2024 15:42:20 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/logstash/</guid><content><![CDATA[&lt;h1 id=&#34;logstash&#34;&gt;Logstash&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;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 Loki 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 from Promtail 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]

    [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;&lt;strong&gt;Note:&lt;/strong&gt; In version 1.1.0 and greater of this plugin you can also specify a list of labels to allowlist via the &lt;code&gt;include_fields&lt;/code&gt; configuration.&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;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;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;h3 id=&#34;insecure_skip_verify&#34;&gt;insecure_skip_verify&lt;/h3&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;]
  }
  # stdout { codec =&amp;gt; rubydebug }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="logstash">Logstash&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;h2 id="installation">Installation&lt;/h2>
&lt;h3 id="local">Local&lt;/h3>
&lt;p>If you need to install the Loki output plugin manually you can do simply so by using the command below:&lt;/p></description></item><item><title>k6 load testing</title><link>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/k6/</link><pubDate>Mon, 14 Apr 2025 21:05:47 +0000</pubDate><guid>https://grafana.com/docs/enterprise-logs/v1.9.x/loki/clients/k6/</guid><content><![CDATA[&lt;h1 id=&#34;k6-loki-extension-load-testing&#34;&gt;k6 Loki extension load testing&lt;/h1&gt;
&lt;p&gt;Grafana &lt;a href=&#34;https://k6.io&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;k6&lt;/a&gt; is a modern load-testing tool.
Its clean and approachable scripting &lt;a href=&#34;https://k6.io/docs/javascript-api/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#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;&lt;code&gt;xk6-loki&lt;/code&gt;&lt;/a&gt; extension 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;https://k6.io/docs/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#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;https://k6.io/docs/using-k6/test-life-cycle/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#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/enterprise-logs/v1.9.x/loki/api/#post-lokiapiv1push&#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/enterprise-logs/v1.9.x/loki/api/#get-lokiapiv1query&#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/enterprise-logs/v1.9.x/loki/api/#get-lokiapiv1query_range&#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/enterprise-logs/v1.9.x/loki/api/#get-lokiapiv1labels&#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/enterprise-logs/v1.9.x/loki/api/#get-lokiapiv1labelnamevalues&#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/enterprise-logs/v1.9.x/loki/api/#series&#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="k6-loki-extension-load-testing">k6 Loki extension load testing&lt;/h1>
&lt;p>Grafana &lt;a href="https://k6.io" target="_blank" rel="noopener noreferrer">k6&lt;/a> is a modern load-testing tool.
Its clean and approachable scripting &lt;a href="https://k6.io/docs/javascript-api/" target="_blank" rel="noopener noreferrer">API&lt;/a>
works locally or in the cloud.
Its configuration makes it flexible.&lt;/p></description></item></channel></rss>