<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Ops Community ⚙️: Alex</title>
    <description>The latest articles on The Ops Community ⚙️ by Alex (@la3mmchen).</description>
    <link>https://community.ops.io/la3mmchen</link>
    <image>
      <url>https://community.ops.io/images/G3Lm1j-ZQcSUzFErQmSNbcgfrgx7FvT_b63Bho7v320/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL3Vz/ZXIvcHJvZmlsZV9p/bWFnZS83MzYvMjlm/OGY1MGQtMTFkOC00/OTU0LTlkMWQtOGI3/MGIwMWUzMTQ0LnBu/Zw</url>
      <title>The Ops Community ⚙️: Alex</title>
      <link>https://community.ops.io/la3mmchen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://community.ops.io/feed/la3mmchen"/>
    <language>en</language>
    <item>
      <title>loki &amp;&amp; logql</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 02 Jun 2022 05:05:01 +0000</pubDate>
      <link>https://community.ops.io/la3mmchen/loki-logql-4pc0</link>
      <guid>https://community.ops.io/la3mmchen/loki-logql-4pc0</guid>
      <description>&lt;h1&gt;
  
  
  loki &amp;amp;&amp;amp; logql
&lt;/h1&gt;

&lt;p&gt;for the last part of my mini series about grafana loki we will now have a look on the query language that is used to power searches.&lt;/p&gt;

&lt;h2&gt;
  
  
  setup some real logs
&lt;/h2&gt;

&lt;p&gt;first of all we need some real data and not mocked data as we've used in the previous articles.&lt;br&gt;
for this we add another container to our stack: a nginx webserver that we use to generate some logs.&lt;/p&gt;

&lt;p&gt;enhance the stack from the (previous)[&lt;a href="https://community.ops.io/la3mmchen/loki-vector-21cf"&gt;https://community.ops.io/la3mmchen/loki-vector-21cf&lt;/a&gt;] article. note the change volume for the vector container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;(...)&lt;/span&gt;
  &lt;span class="s"&gt;vector&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timberio/vector:0.21.X-alpine"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/vector"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/config/main.yaml"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./vector/main.yaml:/config/main.yaml&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx/logs/:/logs&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nginx"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8080:80&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx/logs/access.log:/var/log/nginx/access.log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before starting the stack create the subdirectory and an empty file with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; nginx/logs
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;nginx/logs/access.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup the nginx write its access log to a local folder (&lt;code&gt;nginx/logs/&lt;/code&gt;) that is mounted into the vector container to be consumed.&lt;br&gt;
vector should now send every line to loki.&lt;/p&gt;
&lt;h2&gt;
  
  
  create some requests
&lt;/h2&gt;

&lt;p&gt;lets create one hundred random requests and let vector send them to loki:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..100&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;curl localhost:8080/&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nginx will serve a &lt;code&gt;404 Not Found&lt;/code&gt; but this doesn't matter as we've got something in our access log.&lt;/p&gt;

&lt;h2&gt;
  
  
  browse the logs
&lt;/h2&gt;

&lt;p&gt;Right after creating the request you should see them in Loki. For this we can use logcli but you also can do the queries in the browser.&lt;/p&gt;

&lt;p&gt;We first lookup what labels are there and what possible values for the label "file" are.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli labels
Creating loki_logcli_run ... &lt;span class="k"&gt;done
&lt;/span&gt;http://loki:3100/loki/api/v1/labels?end&lt;span class="o"&gt;=&lt;/span&gt;1654114422211392500&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1654110822211392500
__name__
file
forwarder
&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli labels file
Creating loki_logcli_run ... &lt;span class="k"&gt;done
&lt;/span&gt;http://loki:3100/loki/api/v1/label/file/values?end&lt;span class="o"&gt;=&lt;/span&gt;1654114440666947800&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1654110840666947800
/logs/access.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards we want to see the log stream for the access log. We do this by executing a &lt;code&gt;query&lt;/code&gt; and searching log streams that contain the label &lt;code&gt;file&lt;/code&gt; with the value &lt;code&gt;/logs/access.log&lt;/code&gt;. In our case this is just one log stream, but in reality there can be multiple log streams.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli query &lt;span class="s1"&gt;'{file="/logs/access.log"}'&lt;/span&gt;
Creating loki_logcli_run ... &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;:&lt;span class="s2"&gt;"/logs/access.log"&lt;/span&gt;,&lt;span class="s2"&gt;"host"&lt;/span&gt;:&lt;span class="s2"&gt;"7fdf7d95debe"&lt;/span&gt;,&lt;span class="s2"&gt;"message"&lt;/span&gt;:&lt;span class="s2"&gt;"172.23.0.1 - - [01/Jun/2022:20:12:01 +0000] &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;GET /100 HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; 404 153 &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;curl/7.79.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,&lt;span class="s2"&gt;"source_type"&lt;/span&gt;:&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see some of the requests you've done in the output of the logcli command. &lt;/p&gt;

&lt;p&gt;lets search a certain request. We do this by sending the log stream to a filter operator &lt;code&gt;|=&lt;/code&gt; that matches equality to a search string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli query &lt;span class="s1"&gt;'{file="/logs/access.log"} |= "/44"'&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;){&lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;:&lt;span class="s2"&gt;"/logs/access.log"&lt;/span&gt;,&lt;span class="s2"&gt;"host"&lt;/span&gt;:&lt;span class="s2"&gt;"7fdf7d95debe"&lt;/span&gt;,&lt;span class="s2"&gt;"message"&lt;/span&gt;:&lt;span class="s2"&gt;"172.23.0.1 - - [01/Jun/2022:20:11:59 +0000] &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;GET /44 HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; 404 153 &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;curl/7.79.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,&lt;span class="s2"&gt;"source_type"&lt;/span&gt;:&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also apply regular expressions and combine multiple filter. In this theoretical case we first select all log events in the stream that has a regex match on `/4.*" and the filter out the event(s) that matches "/41".&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
$ docker-compose run logcli query '{file=~"/logs/acccess.*"} |~ "/4.*" |= "/41"'&lt;br&gt;
(..)&lt;br&gt;
Common labels: {file="/logs/access.log", forwarder="vector"}&lt;br&gt;
2022-06-01T20:11:59Z {} {"file":"/logs/access.log","host":"7fdf7d95debe","message":"172.23.0.1 - - [01/Jun/2022:20:11:59 +0000] \"GET /41 HTTP/1.1\" 404 153 \"-\" \"curl/7.79.1\" \"-\"","source_type":"file"}&lt;br&gt;
(..)&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And "like prometheus" we can also do regex matches on the label filtering if you've seen in the above example: &lt;code&gt;file=~"/logs/acccess.*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Thats basically a rough introduction into LogQl. Read more at the (official documentation)[&lt;a href="https://grafana.com/docs/loki/latest/logql/"&gt;https://grafana.com/docs/loki/latest/logql/&lt;/a&gt;] and start playing around with it.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>loki</category>
      <category>logs</category>
      <category>sre</category>
    </item>
    <item>
      <title>loki &amp;&amp; vector</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 01 Jun 2022 03:55:11 +0000</pubDate>
      <link>https://community.ops.io/la3mmchen/loki-vector-21cf</link>
      <guid>https://community.ops.io/la3mmchen/loki-vector-21cf</guid>
      <description>&lt;h1&gt;
  
  
  loki &amp;amp;&amp;amp; vector
&lt;/h1&gt;

&lt;p&gt;during our past (experiments)[&lt;a href="https://community.ops.io/la3mmchen/loki-grafana-1i9d"&gt;https://community.ops.io/la3mmchen/loki-grafana-1i9d&lt;/a&gt;] with loki we created events in loki via curl. this created just a homeopathic amount of events so lets now bring in a logshipper that can talk to loki.&lt;/p&gt;

&lt;p&gt;Looking around we can see at (Loki clients)[&lt;a href="https://grafana.com/docs/loki/latest/clients/"&gt;https://grafana.com/docs/loki/latest/clients/&lt;/a&gt;] a curated list from Grafana. The most prominent solution is (Promtail)[&lt;a href="https://grafana.com/docs/loki/latest/clients/promtail/"&gt;https://grafana.com/docs/loki/latest/clients/promtail/&lt;/a&gt;] a logshipper thats part of the Loki project.&lt;/p&gt;

&lt;h2&gt;
  
  
  vector.dev
&lt;/h2&gt;

&lt;p&gt;At work we use another logshipper because of its versatility in handling inputs and outputs: (vector)[&lt;a href="https://vector.dev/"&gt;https://vector.dev/&lt;/a&gt;], an agent solution from data dog.&lt;/p&gt;

&lt;p&gt;so lets try to enrich our existing compose-stack with a vector instance that speaks with loki. for this we first need a configuration for loki and some directory to store content in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; vector/logs
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt;&amp;gt;vector/main.yaml
---
data_dir: /tmp
timezone: local

sources:
  samplelogs:
    type: file
    include:
      - "/logs/*.log"
    exclude: []
    ignore_older_secs: 999999

sinks:
  loki:
    type: loki
    inputs:
      - samplelogs
    endpoint: "http://loki:3100"
    encoding:
      codec: json
    labels:
      forwarder: vector
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now grep some example logs and move them to &lt;code&gt;./vector/logs/*log&lt;/code&gt;. If you don't mind the content of the data sent to Loki just do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker info &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; vector/logs/docker.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  enhance compose stack
&lt;/h2&gt;

&lt;p&gt;enhance the existing stack from the (previous)[&lt;a href="https://community.ops.io/la3mmchen/loki-grafana-1i9d"&gt;https://community.ops.io/la3mmchen/loki-grafana-1i9d&lt;/a&gt;] article with the following block and start your docker-compose stack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;(...)&lt;/span&gt;
  &lt;span class="s"&gt;vector&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timberio/vector:0.21.X-alpine"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/vector"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/config/main.yaml"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./vector/main.yaml:/config/main.yaml&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./vector/logs/:/logs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see some entry's if you browse logs, lets check fast via logcli:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli series &lt;span class="nt"&gt;--analyze-labels&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
Creating loki_logcli_run ... &lt;span class="k"&gt;done
&lt;/span&gt;http://loki:3100/loki/api/v1/series?end&lt;span class="o"&gt;=&lt;/span&gt;1654024447473483400&amp;amp;match&lt;span class="o"&gt;=&lt;/span&gt;%7B%7D&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1654020847473483400
Total Streams:  1
Unique Labels:  1

Label Name  Unique Values  Found In Streams
forwarder   1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this tells us we've got one stream going into loki. this is because we've attached one label to the logs we've send to grafana loki (&lt;code&gt;forwarder&lt;/code&gt;) so therefore loki just saves on stream for us.&lt;br&gt;
Lets change this by attaching the filename as label to the streams; change the vector config to in the labels section to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;forwarder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vector&lt;/span&gt;
      &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells vector to attach another label with the value of the parsed file to the log stream. After you've restarted vector you can send another example file, e.g. &lt;code&gt;docker --help &amp;gt; vector/logs/docker-help.log&lt;/code&gt; and we should now see more within our stats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli series &lt;span class="nt"&gt;--analyze-labels&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
Creating loki_logcli_run ... &lt;span class="k"&gt;done
&lt;/span&gt;http://loki:3100/loki/api/v1/series?end&lt;span class="o"&gt;=&lt;/span&gt;1654027368307655600&amp;amp;match&lt;span class="o"&gt;=&lt;/span&gt;%7B%7D&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1654023768307655600
Total Streams:  2
Unique Labels:  2

Label Name  Unique Values  Found In Streams
forwarder   1              2
file        1              1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to check the available streams in Grafana, it should look somehow like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/bBdBQuXAr2mD_a76NhmgtmPLVwin4ovq1emw-sUjXSM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZjdjg2/Z2wxcWNoOG9kbDB1/NG0wLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/bBdBQuXAr2mD_a76NhmgtmPLVwin4ovq1emw-sUjXSM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZjdjg2/Z2wxcWNoOG9kbDB1/NG0wLnBuZw" alt="Screenshot from Grafana" width="810" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  follow up
&lt;/h2&gt;

&lt;p&gt;in the next article we will have a look at LogQl that enables you so browse the store information.&lt;/p&gt;

&lt;h2&gt;
  
  
  appendix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;loki&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/loki:2.5.0"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3100:3100"&lt;/span&gt;
  &lt;span class="na"&gt;logcli&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/logcli:2.5.0-amd64"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LOKI_ADDR=http://loki:3100"&lt;/span&gt;
  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/grafana:8.5.3"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./grafana-provision:/etc/grafana/provisioning&lt;/span&gt;
  &lt;span class="na"&gt;vector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timberio/vector:0.21.X-alpine"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/vector"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/config/main.yaml"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./vector/main.yaml:/config/main.yaml&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./vector/logs/:/logs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devops</category>
      <category>loki</category>
      <category>logs</category>
      <category>sre</category>
    </item>
    <item>
      <title>loki &amp;&amp; grafana</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 31 May 2022 07:45:51 +0000</pubDate>
      <link>https://community.ops.io/la3mmchen/loki-grafana-1i9d</link>
      <guid>https://community.ops.io/la3mmchen/loki-grafana-1i9d</guid>
      <description>&lt;h1&gt;
  
  
  loki &amp;amp;&amp;amp; grafana
&lt;/h1&gt;

&lt;p&gt;in my previously written articles i explained what &lt;a href="https://community.ops.io/la3mmchen/grafana-loki-28b9"&gt;loki&lt;/a&gt; is and how we can setup &lt;a href="https://community.ops.io/la3mmchen/loki-curl-logcli-nc5"&gt;loki via docker-compose&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  finally: some GUI
&lt;/h2&gt;

&lt;p&gt;this time we add a grafana instance to our docker-compsose stack to talk to our loki instance. and finally we get some fancy user interface.&lt;/p&gt;

&lt;p&gt;lets add a grafana instance to our docker-compose stack and provide a loki datasource during startup.&lt;/p&gt;

&lt;p&gt;First provide a datasource definition in the folder you've located the docker-compose file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; grafana-provision/datasources
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt;&amp;gt;grafana-provision/datasources/auto.yaml
apiVersion: 1

datasources:
  - name: Loki
    type: loki
    access: proxy
    url: http://loki:3100
    jsonData:
      maxLines: 1000
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;enhance the compose stack with an additional instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;(...)&lt;/span&gt;
  &lt;span class="s"&gt;grafana&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/grafana:8.5.3"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./grafana-provision:/etc/grafana/provisioning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  access loki
&lt;/h2&gt;

&lt;p&gt;upon starting the compose stack you should now have a working datasource in the configuration/datasources panel and should be able to find a datasource "loki" in the dropdown in the explore mode. Navigate your browser to &lt;a href="http://localhost:3000/datasources/"&gt;http://localhost:3000/datasources/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;if you've freshly started the compose stack the explore feature is not quite useful as there is nothing to be explored.&lt;/p&gt;

&lt;h2&gt;
  
  
  add some data
&lt;/h2&gt;

&lt;p&gt;remembering the commands from the previous article we create some data via curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:3100/loki/api/v1/push &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"streams": [{ "stream": { "app": "app1" }, "values": [ [ "1653937064000000000", "random log line" ] ] }]}'&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:3100/loki/api/v1/push &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"streams": [{ "stream": { "app": "app2" }, "values": [ [ "1653937064000000000", "other random log line" ] ] }]}'&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:3100/loki/api/v1/push &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"streams": [{ "stream": { "app": "app3" }, "values": [ [ "1653937064000000000", "another random log line" ] ] }]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;hint: you might have to create a new timestamp via &lt;code&gt;TIMESTAMP="&lt;/code&gt;date +%s&lt;code&gt;000000000" echo ${TIMESTAMP}&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  browse logs
&lt;/h2&gt;

&lt;p&gt;if you followed along you should now see the following selectable labels in your browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/yJ0RxD6_Cicc359Q9rm94HWglcQcQVAfSpDo04KbuQU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFhNHlm/OHhybXZ3c241cGow/cXJoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/yJ0RxD6_Cicc359Q9rm94HWglcQcQVAfSpDo04KbuQU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFhNHlm/OHhybXZ3c241cGow/cXJoLnBuZw" alt="Screenshot from Grafana" width="880" height="780"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;select one label value and hit "show logs" and you should see the previously injected log events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/pw2YYEn11fR0i-Wv9cE6wByamj4wymN0am_d0y3T3yI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzlodmp3/cXp4dGZjcWJlbGR2/NnlzLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/pw2YYEn11fR0i-Wv9cE6wByamj4wymN0am_d0y3T3yI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzlodmp3/cXp4dGZjcWJlbGR2/NnlzLnBuZw" alt="Screenshot from Grafana with selected Logs" width="880" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  closing thoughts
&lt;/h2&gt;

&lt;p&gt;thats it basically. in the upcoming post we select a log shipper that speaks with loki. after that we have a look on LogQl, the query language that you've now already used a little bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  complete compose-stack
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;loki&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/loki:2.5.0"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3100:3100"&lt;/span&gt;
  &lt;span class="na"&gt;logcli&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/logcli:2.5.0-amd64"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LOKI_ADDR=http://loki:3100"&lt;/span&gt;
  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/grafana:8.5.3"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./grafana-provision:/etc/grafana/provisioning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devops</category>
      <category>loki</category>
      <category>logs</category>
      <category>sre</category>
    </item>
    <item>
      <title>loki &amp;&amp; curl &amp;&amp; logcli</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 30 May 2022 04:59:28 +0000</pubDate>
      <link>https://community.ops.io/la3mmchen/loki-curl-logcli-nc5</link>
      <guid>https://community.ops.io/la3mmchen/loki-curl-logcli-nc5</guid>
      <description>&lt;p&gt;With &lt;a href="https://community.ops.io/la3mmchen/grafana-loki-28b9"&gt;https://community.ops.io/la3mmchen/grafana-loki-28b9&lt;/a&gt; I've shared some words on Loki as an introduction. &lt;/p&gt;

&lt;p&gt;Lets follow up with some practical stuff: How can we run Loki an our local notebook with docker-compose? &lt;/p&gt;

&lt;h2&gt;
  
  
  Loki
&lt;/h2&gt;

&lt;p&gt;As Grafana provides a good enough container images we just use the one from &lt;a href="https://hub.docker.com/r/grafana/loki"&gt;docker hub&lt;/a&gt; to get a local instance running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;loki&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/loki:2.5.0"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3100:3100"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As Loki follows the unix philosophy "Do One Thing and Do It Well" it's just a backend to send logs to and to query logs from. &lt;br&gt;
Plain speaking: there is no graphical user interface in the Loki server. &lt;/p&gt;

&lt;p&gt;We interact with the Loki instance with curl using the &lt;a href="https://grafana.com/docs/loki/latest/api/"&gt;http api&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt; curl http://localhost:3100/ready  
ready
&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://localhost:3100/loki/api/v1/labels
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;:&lt;span class="s2"&gt;"success"&lt;/span&gt;,&lt;span class="s2"&gt;"data"&lt;/span&gt;:[&lt;span class="s2"&gt;"__name__"&lt;/span&gt;&lt;span class="o"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the second request shows there are not many labels in the system yet. &lt;/p&gt;

&lt;p&gt;Lets change this.&lt;/p&gt;

&lt;h2&gt;
  
  
  interact with curl
&lt;/h2&gt;

&lt;p&gt;Loki offers a http api to send metrics. The data format is described at &lt;a href="https://grafana.com/docs/loki/latest/api/#post-lokiapiv1push"&gt;http push api&lt;/a&gt;, we use the following curl to create a new event stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:3100/loki/api/v1/push &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{"streams": [{ "stream": { "app": "app1" }, "values": [ [ "1653855518000000000", "random log line" ] ] }]}'&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://localhost:3100/loki/api/v1/labels
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;:&lt;span class="s2"&gt;"success"&lt;/span&gt;,&lt;span class="s2"&gt;"data"&lt;/span&gt;:[&lt;span class="s2"&gt;"__name__"&lt;/span&gt;,&lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="o"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the second curl there is now a new label named "app". We can explore possible values for this label with the following curl.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://localhost:3100/loki/api/v1/label/app/values
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;:&lt;span class="s2"&gt;"success"&lt;/span&gt;,&lt;span class="s2"&gt;"data"&lt;/span&gt;:[&lt;span class="s2"&gt;"app1"&lt;/span&gt;&lt;span class="o"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finaly see the stream with this label:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="nt"&gt;-Ss&lt;/span&gt;  http://localhost:3100/loki/api/v1/query_range &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'query={app="app1"}'&lt;/span&gt; | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"success"&lt;/span&gt;,
&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="s2"&gt;"values"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
          &lt;span class="o"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"1653855518000000000"&lt;/span&gt;,
            &lt;span class="s2"&gt;"random log line"&lt;/span&gt;
          &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(output shorted)&lt;/p&gt;

&lt;h2&gt;
  
  
  logcli
&lt;/h2&gt;

&lt;p&gt;A more covenient way to interact with Loki from the command line is using &lt;a href="https://grafana.com/docs/loki/latest/tools/logcli/"&gt;logcli&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ LOKI_ADDR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:3100 logcli labels
http://localhost:3100/loki/api/v1/labels?end&lt;span class="o"&gt;=&lt;/span&gt;1653856566774536000&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1653852966774536000
__name__
app
&lt;span class="nv"&gt;$ LOKI_ADDR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:3100 logcli query &lt;span class="s1"&gt;'{app=~".+"}'&lt;/span&gt;
http://localhost:3100/loki/api/v1/query_range?direction&lt;span class="o"&gt;=&lt;/span&gt;BACKWARD&amp;amp;end&lt;span class="o"&gt;=&lt;/span&gt;1653856568404563000&amp;amp;limit&lt;span class="o"&gt;=&lt;/span&gt;30&amp;amp;query&lt;span class="o"&gt;=&lt;/span&gt;%7Bapp%3D~%22.%2B%22%7D&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1653852968404563000
Common labels: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"app1"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
2022-05-29T22:18:38+02:00 &lt;span class="o"&gt;{}&lt;/span&gt; random log line
http://localhost:3100/loki/api/v1/query_range?direction&lt;span class="o"&gt;=&lt;/span&gt;BACKWARD&amp;amp;end&lt;span class="o"&gt;=&lt;/span&gt;1653855518000000001&amp;amp;limit&lt;span class="o"&gt;=&lt;/span&gt;30&amp;amp;query&lt;span class="o"&gt;=&lt;/span&gt;%7Bapp%3D~%22.%2B%22%7D&amp;amp;start&lt;span class="o"&gt;=&lt;/span&gt;1653852968404563000
Common labels: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"app1"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in case you do not want to install &lt;code&gt;logcli&lt;/code&gt; locally just add another container to our docker-compose setup from the beginning of this article:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;(..)&lt;/span&gt;
  &lt;span class="s"&gt;logcli&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/logcli:2.5.0-amd64"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LOKI_ADDR=http://loki:3100"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with this container you can just do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose run logcli labels
Creating loki_logcli_run ... &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;..&lt;span class="o"&gt;)&lt;/span&gt;
__name__
app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  following up
&lt;/h2&gt;

&lt;p&gt;in the next post we will add a grafana instance to our docker-compose that will enable us to click something ;-)&lt;/p&gt;

&lt;h2&gt;
  
  
  references
&lt;/h2&gt;

&lt;h3&gt;
  
  
  links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://community.ops.io/la3mmchen/grafana-loki-28b9"&gt;introduction to loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://grafana.com/docs/loki/latest/installation/docker/"&gt;documentation for loki with docker&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  code reference
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;loki&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/loki:2.5.0"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3100:3100"&lt;/span&gt;
  &lt;span class="na"&gt;logcli&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grafana/logcli:2.5.0-amd64"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LOKI_ADDR=http://loki:3100"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devops</category>
      <category>loki</category>
      <category>logs</category>
      <category>sre</category>
    </item>
    <item>
      <title>Grafana Loki</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Sun, 29 May 2022 17:55:33 +0000</pubDate>
      <link>https://community.ops.io/la3mmchen/grafana-loki-28b9</link>
      <guid>https://community.ops.io/la3mmchen/grafana-loki-28b9</guid>
      <description>&lt;p&gt;Debugging applications in a distributed system like kubernetes or cloud environments might be hard without a tool at hand that collect logs and let you browse them.&lt;/p&gt;

&lt;p&gt;There are quite a few players in this game - e.g. Elasticsearch, Splunk, or DataDog.&lt;/p&gt;

&lt;p&gt;Let me introduce one possible option to host a logfile collector because i found no other article that covers it.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://github.com/grafana/loki"&gt;Loki&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;It is fast. and can run with less overhead. Bonus point: it integrates very well in you're probably already existing central dashboarding solution Grafana.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"just like prometheus. but for logs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consider log events as a stream like prometheus metrics. If you're familiar with prometheus you know the following notation. This represents one metric (&lt;code&gt;up&lt;/code&gt;) with two different label values that represents the state of two different applications. Prometheus save timestamps and values for those two streams and let you query the results, e.g. via Grafana.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;up&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;app_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"login-api"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
up&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;app_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"logout-api"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Loki also thinks of incoming data as streams and distinguishes them with labels. In the following example you see one example stream with some labels. i removed some labels for brevity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;:&lt;span class="s2"&gt;"/var/log/pods/ingress_ingress-nginx-controller-5fc96d49ff-986gd_ab5b1165-cbe7-437d-a1a1-8d32473929cc/controller/0.log"&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt; request&lt;span class="s2"&gt;":{"&lt;/span&gt;latency&lt;span class="s2"&gt;":"&lt;/span&gt;0.012 s&lt;span class="s2"&gt;","&lt;/span&gt;protocol&lt;span class="s2"&gt;":"&lt;/span&gt;HTTP/1.1&lt;span class="s2"&gt;","&lt;/span&gt;referer&lt;span class="s2"&gt;":"","&lt;/span&gt;remoteIp&lt;span class="s2"&gt;":"&lt;/span&gt;&amp;lt;...&amp;gt;&lt;span class="s2"&gt;","&lt;/span&gt;remoteUser&lt;span class="s2"&gt;":"","&lt;/span&gt;requestMethod&lt;span class="s2"&gt;":"&lt;/span&gt;GET&lt;span class="s2"&gt;","&lt;/span&gt;requestPlain&lt;span class="s2"&gt;":"&lt;/span&gt;GET /ping HTTP/1.1&lt;span class="s2"&gt;","&lt;/span&gt;requestSize&lt;span class="s2"&gt;":"&lt;/span&gt;205&lt;span class="s2"&gt;","&lt;/span&gt;requestTime&lt;span class="s2"&gt;":"&lt;/span&gt;0.015&lt;span class="s2"&gt;","&lt;/span&gt;requestUrl&lt;span class="s2"&gt;":"&lt;/span&gt;&amp;lt;..&amp;gt;&lt;span class="s2"&gt;","&lt;/span&gt;responseSize&lt;span class="s2"&gt;":"&lt;/span&gt;14&lt;span class="s2"&gt;","&lt;/span&gt;status&lt;span class="s2"&gt;":"&lt;/span&gt;200&lt;span class="s2"&gt;","&lt;/span&gt;userAgent&lt;span class="s2"&gt;":"&lt;/span&gt;Blackbox Exporter/0.20.0&lt;span class="s2"&gt;"},"&lt;/span&gt;source_type&lt;span class="s2"&gt;":"&lt;/span&gt;kubernetes_logs&lt;span class="s2"&gt;","&lt;/span&gt;stream&lt;span class="s2"&gt;":"&lt;/span&gt;stdout&lt;span class="s2"&gt;"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For incoming events Loki normalizes the volatile parts of the fields and store the occurring timestamp whenever an event matching this stream is entering the system. &lt;/p&gt;

&lt;p&gt;This makes it easy to store lot of similar event that for example are produced in kubernetes clusters. Also it does not need lot of disk space for gathering logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not Elasticsearch?
&lt;/h2&gt;

&lt;p&gt;The still state-of-the-art tooling for collection logs is the elastic stack.&lt;/p&gt;

&lt;p&gt;Elasticsearch as search tool sends every single event into the underlying Lucene indices. Without any optimization this makes a beautiful search experience for the user because they can execute full-text searches on the collected events.&lt;/p&gt;

&lt;p&gt;This might lead to increased resource usage, though. &lt;/p&gt;

&lt;h2&gt;
  
  
  Upcoming
&lt;/h2&gt;

&lt;p&gt;I'll compose more articles on this topic. &lt;/p&gt;

&lt;p&gt;Following up: how to setup a local Loki instance with docker-compose to be able to test, a selection of log shipper that works with Loki.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>logs</category>
      <category>loki</category>
      <category>sre</category>
    </item>
  </channel>
</rss>
