<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Loki &#8211; Johnny Morano&#039;s Tech Articles</title>
	<atom:link href="https://jmorano.moretrix.com/tag/loki/feed/" rel="self" type="application/rss+xml" />
	<link>https://jmorano.moretrix.com</link>
	<description>Ramblings of an old-fashioned space cowboy</description>
	<lastBuildDate>Tue, 22 Nov 2022 07:21:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>

<image>
	<url>https://jmorano.moretrix.com/wp-content/uploads/2022/04/cropped-jmorano_emblem-32x32.png</url>
	<title>Loki &#8211; Johnny Morano&#039;s Tech Articles</title>
	<link>https://jmorano.moretrix.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>A monitoring solution with Docker</title>
		<link>https://jmorano.moretrix.com/2022/11/a-monitoring-solution-with-docker/</link>
					<comments>https://jmorano.moretrix.com/2022/11/a-monitoring-solution-with-docker/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Tue, 22 Nov 2022 07:21:51 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Containers]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Grafana]]></category>
		<category><![CDATA[Loki]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Prometheus]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1587</guid>

					<description><![CDATA[Docker Compose is a great way to set up small test environments locally or remotely. It allows to&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Docker Compose is a great way to set up small test environments locally or remotely. It allows to define your infrastructure as code and does not require any prerequisite tasks or after deployments tasks.</p>



<p>The Docker installation is well documented at <a rel="noreferrer noopener" href="https://docs.docker.com/get-docker/" target="_blank">https://docs.docker.com/get-docker/</a> and is well supported amongst the most popular operating systems. The installation itself will not be covered in this article. If you want to get familiar with the details of Docker, start with the documentation at <a href="https://docs.docker.com/get-started/" target="_blank" rel="noreferrer noopener">https://docs.docker.com/get-started/</a>.</p>



<p>All code used in this article is available at: <a rel="noreferrer noopener" href="https://github.com/insani4c/docker-monitoring-stack" target="_blank">https://github.com/insani4c/docker-monitoring-stack</a>. </p>



<p>In this article, we will see how to set up a monitoring solution based on:</p>



<ul class="wp-block-list">
<li><a href="https://prometheus.io/" data-type="URL" data-id="https://prometheus.io/" target="_blank" rel="noreferrer noopener">Prometheus</a></li>



<li><a href="https://prometheus.io/docs/guides/node-exporter/" data-type="URL" data-id="https://prometheus.io/docs/guides/node-exporter/" target="_blank" rel="noreferrer noopener">Prometheus Node Exporter</a></li>



<li><a href="https://github.com/prometheus/blackbox_exporter" data-type="URL" data-id="https://github.com/prometheus/blackbox_exporter" target="_blank" rel="noreferrer noopener">Prometheus Black Exporter</a></li>



<li><a href="https://github.com/prometheus/snmp_exporter" data-type="URL" data-id="https://github.com/prometheus/snmp_exporter" target="_blank" rel="noreferrer noopener">Prometheus SNMP Exporter</a></li>



<li><a href="https://grafana.com/oss/loki/" data-type="URL" data-id="https://grafana.com/oss/loki/" target="_blank" rel="noreferrer noopener">Loki</a></li>



<li><a href="https://grafana.com/docs/loki/latest/clients/promtail/" data-type="URL" data-id="https://grafana.com/docs/loki/latest/clients/promtail/" target="_blank" rel="noreferrer noopener">Promtail</a></li>



<li><a href="https://grafana.com/" data-type="URL" data-id="https://grafana.com/" target="_blank" rel="noreferrer noopener">Grafana</a></li>
</ul>



<p>To monitor the deployed containers, we will also deploy <a rel="noreferrer noopener" href="https://github.com/google/cadvisor" data-type="URL" data-id="https://github.com/google/cadvisor" target="_blank">Google&#8217;s cadvisor</a> container, to get some interesting statistics and details in our Prometheus/ Grafana setup.</p>



<p>The Docker Compose file, called <code data-enlighter-language="generic" class="EnlighterJSRAW">docker-compose.yml</code>, contains all the information of the infrastructure such as:</p>



<ul class="wp-block-list">
<li>network information</li>



<li>volumes</li>



<li>services (the containers)</li>



<li>&#8230;</li>
</ul>



<p>Let&#8217;s start from the top of the file.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="dockerfile" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">version: '3.8'

name: docmon

volumes:
  grafana-data: {}
  alertmanager-data: {}
  prometheus-data: {}
  loki-data: {}
</pre>



<p>At first at <code data-enlighter-language="generic" class="EnlighterJSRAW">line 1</code>, the version Docker Compose version is specified, to define which specifications are allowed. At <code data-enlighter-language="generic" class="EnlighterJSRAW">line 3</code> a name for the container group or stack is set. And finally starting from <code data-enlighter-language="generic" class="EnlighterJSRAW">line 5</code>, data volumes (think <em>disks</em>) are defined, which will be used by the containers. These are persistent data volumes which will be reused unless the container has been completely removed.</p>



<p>Next, we will define the services in the <code data-enlighter-language="generic" class="EnlighterJSRAW">docker-compose.yml</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="dockerfile" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="cadvisor and pronetheus" data-enlighter-group="docker-compose.yml">services:
  cadvisor:
    image: 'gcr.io/cadvisor/cadvisor:latest'
    container_name: cadvisor
    restart: always
    mem_limit: 512m
    mem_reservation: 32m
    # ports: 
    #   - '8880:8080'
    volumes:
      - '/:/rootfs:ro'
      - '/var/run:/var/run:ro'
      - '/sys:/sys:ro'
      - '/var/lib/docker/:/var/lib/docker:ro'
      - '/dev/disk/:/dev/disk:ro'
    privileged: true
    devices: 
      - '/dev/kmsg:/dev/kmsg'

  prometheus:
    image: 'prom/prometheus:latest'
    container_name: prometheus
    restart: always
    mem_limit: 2048m
    mem_reservation: 256m
    cpus: 2
    # ports:
    #   - '9090:9090'
    volumes:
      - '$PROMETHEUS_HOME/config:/etc/prometheus'
      - 'prometheus-data:/prometheus'
    extra_hosts:
      myrouter: 192.168.1.1
      myswitch: 192.168.1.10
    depends_on:
      - cadvisor
</pre>



<p>Containers are defined as <code data-enlighter-language="generic" class="EnlighterJSRAW">services</code>. Each <code data-enlighter-language="generic" class="EnlighterJSRAW">service</code> will require at least:</p>



<ul class="wp-block-list">
<li>a service name (example <code data-enlighter-language="generic" class="EnlighterJSRAW">line 2</code> and <code data-enlighter-language="generic" class="EnlighterJSRAW">line 20</code>)</li>



<li>an <code data-enlighter-language="generic" class="EnlighterJSRAW">image</code> definition</li>
</ul>



<p>All other options are optional or required by specific images. </p>



<p>The first image or container defined in the above example is <code data-enlighter-language="generic" class="EnlighterJSRAW">cadvisor</code>. This service provides statistics from Docker and the deployed containers to Prometheus. To be able to provide this information, the container must have read access to certain file paths or sockets on the hypervisor (read: the server where the Docker containers will be running). These are provided in the <code data-enlighter-language="generic" class="EnlighterJSRAW">volumes</code> section of the container. Here, directory paths on the hypervisor will be provided as mount partitions in the container, and they will be mounted with the <code data-enlighter-language="generic" class="EnlighterJSRAW">readonly</code> (<code data-enlighter-language="generic" class="EnlighterJSRAW">:ro</code>) parameter so that the container can&#8217;t make any changes to them.</p>



<p>Furthermore it provides access to a <code data-enlighter-language="generic" class="EnlighterJSRAW">device</code> (to read kernel messages), set <code data-enlighter-language="generic" class="EnlighterJSRAW">memory</code> and <code data-enlighter-language="generic" class="EnlighterJSRAW">cpu</code> limits and will run the container in <code data-enlighter-language="generic" class="EnlighterJSRAW">privilege</code> mode. The <code data-enlighter-language="generic" class="EnlighterJSRAW">ports</code> section has been put in comments, as it isn&#8217;t really require to expose ports, or make them available outside the Docker ecosystem. In our example, only Prometheus must be able to connect to it, and since Prometheus will be deployed as a container, we don&#8217;t need to be able to access the web service running on the container to read out the metrics or see the statistics.</p>



<p>The next container defined is called <code data-enlighter-language="generic" class="EnlighterJSRAW">prometheus</code>. For this container, <code data-enlighter-language="generic" class="EnlighterJSRAW">volumes</code> will be mounted to provide the Prometheus configuration files and to store the data to the volume called <code data-enlighter-language="generic" class="EnlighterJSRAW">prometheus-data</code>. It also defines an <code data-enlighter-language="generic" class="EnlighterJSRAW">extra_hosts</code>. These are entries that are typically defined in an <code data-enlighter-language="generic" class="EnlighterJSRAW">/etc/hosts</code> file, which Docker does not read from the hypervisor. And instead of deploying or mounting the hypervisor&#8217;s <code data-enlighter-language="generic" class="EnlighterJSRAW">hosts</code> file, extra host mappings can be defined or handed to the container, which is set up in the <code data-enlighter-language="generic" class="EnlighterJSRAW">extra_hosts</code> section as above.</p>



<p>At the end of the <code data-enlighter-language="generic" class="EnlighterJSRAW">prometheus</code> container definition, a <code data-enlighter-language="generic" class="EnlighterJSRAW">depends_on</code> section is configured, which means that the <code data-enlighter-language="generic" class="EnlighterJSRAW">prometheus</code> container won&#8217;t be deployed until the container names defined in that section are up and running.</p>



<p>Next we will define all other containers (see the second tab in the above code block, called <code data-enlighter-language="generic" class="EnlighterJSRAW">the rest</code>).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="dockerfile" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="the rest" data-enlighter-group="docker-compose.yml">  hypervisor:
    image: 'prom/node-exporter:latest'
    container_name: hypervisor
    mem_limit: 128m
    mem_reservation: 32m
    restart: unless-stopped
    volumes:
      - '/:/host:ro,rslave'
      - '/proc:/host/proc:ro'
      - '/sys:/host/sys:ro'
    command:
      - '--path.rootfs=/host'
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
      - '--collector.systemd'
      - '--collector.cgroups'
    depends_on:
      - cadvisor

  prom_snmp:
    image: 'prom/snmp-exporter:latest'
    container_name: prom_snmp
    restart: always
    mem_limit: 128m
    mem_reservation: 32m
    # ports: 
    #   - '9116:9116'
    volumes:
      - '$PROMSNMP_HOME/config:/etc/snmp_exporter'
    extra_hosts:
      myrouter: 192.168.1.1
      myswitch: 192.168.1.10
    depends_on:
      - cadvisor
      - prometheus

  alertmanager:
    image: 'prom/alertmanager:latest'
    container_name: alertmanager
    restart: always
    mem_limit: 256m
    mem_reservation: 32m 
    # ports:
    #   - 9093:9093
    volumes:
      - '$ALERTMANAGER_HOME/config/alertmanager.yml:/etc/alertmanager/config.yml'
      - 'alertmanager-data:/alertmanager'
    command:
      - '--config.file=/etc/alertmanager/config.yml'
      - '--storage.path=/alertmanager'
    depends_on:
      - cadvisor
      - prometheus

  loki:
    image: 'grafana/loki:latest'
    container_name: loki
    restart: always
    mem_limit: 32768m
    mem_reservation: 8192m
    cpus: 6 
    ports:
      - '3100:3100'
    volumes:
      - '$LOKI_HOME/config:/etc/loki'
      - 'loki-data:/loki'
    depends_on:
      - cadvisor
      - prometheus
      - alertmanager

  blackbox_exporter:
    image: 'prom/blackbox-exporter:latest'
    container_name: blackbox_exporter
    restart: always
    mem_limit: 128m
    mem_reservation: 32m
    dns:
      - 8.8.8.8
      - 8.8.4.4
    # ports:
    #   - 9115:9115
    volumes:
      - '$BLACKBOXEXPORTER_HOME/config:/etc/blackboxexporter/'
    command:
      - '--config.file=/etc/blackboxexporter/config.yml'
    depends_on:
      - cadvisor
      - prometheus

  promtail:
    image: grafana/promtail:latest
    container_name: promtail
    restart: always
    mem_limit: 256m
    mem_reservation: 64m
    volumes:
      - $PROMTAIL_HOME/config:/etc/promtail/
      # to read container labels and logs
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
      - '/var/lib/docker/containers:/var/lib/docker/containers:ro'
      - '/var/log/ulog:/var/log/ulog/:ro'
    depends_on:
      - cadvisor
      - loki

  grafana:
    image: 'grafana/grafana:latest'
    container_name: grafana
    restart: always
    mem_limit: 2048m
    mem_reservation: 256m
    ports:
      - '3000:3000'
    volumes:
      - '$GRAFANA_HOME/config:/etc/grafana'
      - 'grafana-data:/var/lib/grafana'
      - '$GRAFANA_HOME/dashboards:/var/lib/grafana/dashboards'
    depends_on:
      - cadvisor
      - prometheus
      - loki
      - alertmanager
</pre>



<p>The rest of the code will deploy:</p>



<ul class="wp-block-list">
<li>a container called <code data-enlighter-language="generic" class="EnlighterJSRAW">hypervisor</code>, which is actually the Prometheus node-exporter for the hypervisor.</li>



<li>a container called <code data-enlighter-language="generic" class="EnlighterJSRAW">prom_snmp</code>, which will retrieve SNMP statistics</li>



<li>a container called <code data-enlighter-language="generic" class="EnlighterJSRAW">blackbox_exporter</code>, which mainly checks webservers and their SSL certificates</li>



<li>a container called <code data-enlighter-language="generic" class="EnlighterJSRAW">promtail</code>, which collects logs and log statistics from the hypervisor</li>



<li>a container called <code data-enlighter-language="generic" class="EnlighterJSRAW">loki</code>, which allows to store and index logs sent to the service by <code data-enlighter-language="generic" class="EnlighterJSRAW">promtail</code> (either container or as a service running on some external server)</li>
</ul>



<p>Finally, the last container deployed is the <code data-enlighter-language="generic" class="EnlighterJSRAW">grafana</code> container. Besides its normal configuration file <code data-enlighter-language="generic" class="EnlighterJSRAW">grafana.ini</code>, the Docker container will also automatically provision (the <code data-enlighter-language="generic" class="EnlighterJSRAW">provisioning</code> sub directory in the <code data-enlighter-language="generic" class="EnlighterJSRAW">config</code> directory) datasources and dashboards so that no manual after-tasks are required once the containers are running.</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="354" height="244" src="https://jmorano.moretrix.com/wp-content/uploads/2022/11/Screenshot-from-2022-11-22-07-52-18.png" alt="" class="wp-image-1595" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/11/Screenshot-from-2022-11-22-07-52-18.png 354w, https://jmorano.moretrix.com/wp-content/uploads/2022/11/Screenshot-from-2022-11-22-07-52-18-300x207.png 300w" sizes="(max-width: 354px) 100vw, 354px" /><figcaption class="wp-element-caption">The grafana files</figcaption></figure>



<p>The datasources can be preconfigured in a YAML file called <code data-enlighter-language="generic" class="EnlighterJSRAW">default.yaml</code>, stored in the <code data-enlighter-language="generic" class="EnlighterJSRAW">provisioning/datasources/</code> sub directory.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="yaml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apiVersion: 1

datasources:
 - name: Alertmanager
   type: alertmanager 
   access: proxy
   orgId: 1
   url: http://alertmanager:9093
   version: 1
   editable: false
   isDefault: false
   uid: DS_ALERTMANAGER
   jsonData:
    implementation: prometheus
 - name: Prometheus
   type: prometheus
   access: proxy
   orgId: 1
   url: http://prometheus:9090
   version: 1
   editable: false
   isDefault: true
   uid: DS_PROMETHEUS
   jsonData:
    alertmanagerUid: DS_ALERTMANAGER
    manageAlerts: true
    prometheusType: Prometheus
    prometheusVersion: 2.39.1
 - name: Loki
   type: loki 
   access: proxy
   orgId: 1
   url: http://loki:3100
   version: 1
   editable: false
   isDefault: false
   uid: DS_LOKI
   jsonData:
    alertmanagerUid: DS_ALERTMANAGER
    manageAlerts: true
</pre>



<p>Same thing goes for dashboards we want to have automatically deployed:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="yaml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apiVersion: 1

providers:
 - name: 'default'
   orgId: 1
   folder: 'Custom'
   folderUid: ''
   type: file
   options:
     path: /var/lib/grafana/dashboards
</pre>



<p>Finally, if Docker is running on multiple network interfaces (for it is a hosted server, or it has internal and external IP addresses), you might want to limit access to the container to specific networks only.</p>



<p>Below is a <code data-enlighter-language="generic" class="EnlighterJSRAW">netfilter</code> example, which allows traffic only coming from <code data-enlighter-language="generic" class="EnlighterJSRAW">192.168.1.0/24</code> and from the network interface <code data-enlighter-language="generic" class="EnlighterJSRAW">enp35so</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">iptables -I DOCKER-USER -i enp35s0 ! -s 192.168.1.0/24 -m conntrack --ctdir ORIGINAL -j DROP</pre>



<p>The chain <code data-enlighter-language="generic" class="EnlighterJSRAW">DOCKER-USER</code> is not flushed by Docker and thus can be created in a general firewall script of <code data-enlighter-language="generic" class="EnlighterJSRAW">netfilter</code> configuration, even at boot time:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">-N DOCKER-USER
-I DOCKER-USER -i enp35s0 ! -s 192.168.1.0/24 -m conntrack --ctdir ORIGINAL -j DROP</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/11/a-monitoring-solution-with-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>IPTables Logs in Loki and Grafana (with Promtail)</title>
		<link>https://jmorano.moretrix.com/2022/04/iptables-logs-in-loki-and-grafana-with-promtail/</link>
					<comments>https://jmorano.moretrix.com/2022/04/iptables-logs-in-loki-and-grafana-with-promtail/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Fri, 01 Apr 2022 08:00:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Grafana]]></category>
		<category><![CDATA[IPTables]]></category>
		<category><![CDATA[Loki]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Promtail]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1310</guid>

					<description><![CDATA[In the previous article (Logging in IPTables with NFLog and ulogd2) rules were created to log certain IPTables&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In the previous article (<a href="https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/" data-type="URL" data-id="https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/">Logging in IPTables with NFLog and ulogd2</a>) rules were created to log certain IPTables rules with the use of <code>NFLOG</code> and <code>ulogd2</code> to a file in JSON format.</p>



<p>With Promtail (<a rel="noreferrer noopener" href="https://grafana.com/docs/loki/latest/clients/promtail/" data-type="URL" data-id="https://grafana.com/docs/loki/latest/clients/promtail/" target="_blank">https://grafana.com/docs/loki/latest/clients/promtail/</a>), the above created log files can be sent to <a rel="noreferrer noopener" href="https://grafana.com/docs/loki/latest/" data-type="URL" data-id="https://grafana.com/docs/loki/latest/" target="_blank">Loki</a> so that they can finally be displayed in <a rel="noreferrer noopener" href="https://grafana.com/grafana/" data-type="URL" data-id="https://grafana.com/grafana/" target="_blank">Grafana</a>.</p>



<p>The installation of both Loki and Grafana are not covered in this article. The installation of Promtail is documented at <a rel="noreferrer noopener" href="https://grafana.com/docs/loki/latest/clients/promtail/installation/" target="_blank">https://grafana.com/docs/loki/latest/clients/promtail/installation/</a>.</p>



<p>Once Promtail is installed, create the following configuration file at <code>/etc/promtail-local-config.yaml</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">server:                                                                                                                                                                                                            
  http_listen_port: 9080                                                                                                                                                                                           
  grpc_listen_port: 0                                                                                                                                                                                              
                                                                                                                                                                                                                   
positions:                                                                                                                                                                                                         
  filename: /var/tmp/promtail_positions.yaml                                                                                                                                                                       
                                                                                                                                                                                                                   
clients:                                                                                                                                                                                                           
  - url: http://loki_server:3100/loki/api/v1/push       
                                                                                                                                                               
scrape_configs:
    - job_name: iptableslogsjson
      static_configs:
      - targets:
          - localhost
        labels:
          instance: myhostname01
          job: iptableslogsjson
          __path__: /var/log/ulog/*json
      pipeline_stages:
      - json:
          expressions:
            timestamp: timestamp
            prefix: '"oob.prefix"'
            src: src_ip
            dst: dest_ip
      - labels:
          timestamp:
          prefix:
          src:
          dst:</pre>



<p>With the above configuration, Promtail will create 4 extra labels per log line:</p>



<ul class="wp-block-list"><li><code>timestamp</code>: Contains the logged timestamp</li><li><code>prefix</code>: the NFLOG prefix string</li><li><code>src</code>: the source IP address</li><li><code>dst</code>: the destination IP address</li></ul>



<p>Once the logs are arriving in Loki, and Loki has been configured as a datasource in Grafana, graphs can be created using <a href="https://grafana.com/docs/loki/latest/logql/" data-type="URL" data-id="https://grafana.com/docs/loki/latest/logql/" target="_blank" rel="noreferrer noopener">LogQL</a>.</p>



<p>Example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sum(rate({job="iptableslogsjson"} [$__interval])) by (prefix)</pre>



<figure class="wp-block-image size-full"><img decoding="async" width="916" height="296" src="https://jmorano.moretrix.com/wp-content/uploads/2022/03/Screenshot-from-2022-03-30-15-29-02.png" alt="" class="wp-image-1311" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/03/Screenshot-from-2022-03-30-15-29-02.png 916w, https://jmorano.moretrix.com/wp-content/uploads/2022/03/Screenshot-from-2022-03-30-15-29-02-300x97.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/03/Screenshot-from-2022-03-30-15-29-02-768x248.png 768w" sizes="(max-width: 916px) 100vw, 916px" /></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/04/iptables-logs-in-loki-and-grafana-with-promtail/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
