Blog  /  Community

Transforming application logs into metrics with Istio and Grafana Cloud

11 Feb 2022 6 min read

Antonio Berben is a Field Engineer working for solo.io on Gloo Mesh (with Istio) and Gloo Edge (with Envoy). He is a Kubernetes enthusiast and his favorite quote is: “I will go anywhere, provided it be forward” from David Livingstone. You can find and follow Antonio on Twitter.

Kim Uyttebrouck is an experienced leader who has a proven track record of working with successful teams in both professional and personal life. He’s a DevOps enthusiast based in Leuven, Belgium, who likes to learn about new technologies. In his free time he trains for short distance triathlons.

Do you actually know what your customers are looking for?

A way to uncover new business opportunities is to analyze your system, collect what you really need, and visualize it through a comprehensive graph!

Log traces are a great place to start because they usually contain useful information on your customers' interests. You just need to transform them.

This blog post will show you how to transform raw data from Istio access logs collected by Promtail into valuable metrics visualized through Grafana Cloud.

The scenario

Your e-commerce platform is selling different pairs of socks. Customers can filter the socks catalog based on their personal interest. You want to find out which pair of socks is most filtered by “formal” or “geek.”

Your architecture will look like this:

Hands-on setup!

Prerequisites:

  • Kubernetes cluster - e.g. Kind
  • Istioctl (this example uses version 1.12.1)
  • Helm
  • Grafana Cloud free account

First, let’s set up your Grafana Cloud stack:

  • Create a free Grafana Cloud account if you don’t already have one.
  • Sign up with existing credentials (Google, Github, etc), create your account, and obtain your own stack on the Grafana Cloud Portal.
  • You will also need to create a Grafana Cloud API key with metrics push privileges!
  • Click on “Send Metrics” next to Prometheus to navigate to Grafana Cloud’s Prometheus Configuration page.
  • Scroll to find the Password/API key section.
  • Click on the blue text “Generate now.” In the new window, make sure to select “MetricsPublisher” from the dropdown Role list when creating your API key.
  • IMPORTANT note: Grafana Cloud’s Prometheus Configuration page also contains the following required information for being able to send Prometheus metrics to Grafana Cloud:

    • Remote Write Endpoint
    • Username / Instance ID
  • Navigate back to the Grafana Cloud Portal and click on “Send Logs” next to Loki. 

On the “Using Grafana with Logs” page, scroll to find the Grafana Data Source settings. You will need the User value when deploying Promtail.

Now, on the Kubernetes cluster, install Helm repositories.

helm repo add grafana https://grafana.github.io/helm-charts
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

Install Istio operator.

istioctl operator init
kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-operator
  namespace: istio-system
spec:
 profile: default
 meshConfig:
   accessLogFile: /dev/stdout
   accessLogFormat: |
     accesslog [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
EOF

Wait until Istio is up and running.

Install the sock-shop application. You can read more about the application design here.

kubectl create ns sock-shop
kubectl label namespace sock-shop istio-injection=enabled --overwrite
kubectl -n sock-shop apply -f  
https://raw.githubusercontent.com/microservices-demo/microservices-demo/master/deploy/kubernetes/complete-demo.yaml 

Verify if all pods have Istio injected. (Each microservice pod should show an extra container which is the Istio sidecar.)

kubectl get pods -n sock-shop

Deploy an Istio gateway and virtual service.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: sock-gateway
 namespace: sock-shop
spec:
 selector:
   istio: ingressgateway 
 servers:
 - port:
     number: 80
     name: http
     protocol: HTTP
   hosts:
   - "*" 
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: sock
 namespace: sock-shop
spec:
 hosts:
 - "*"
 gateways:
 - sock-gateway
 http:
 - match:
   - uri:
       prefix: "/"
   route:
   - destination:
       host: front-end.sock-shop.svc.cluster.local
       port:
         number: 80
EOF

Open a tunnel to the Istio ingress gateway (= service mesh entry-point) to access the sock-shop application.

kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80

The sock-shop application is now available at http://localhost:8080

Install Prometheus with remote_write configuration.

The required details can be found in Grafana Cloud’s Prometheus metrics documentation (see also Prerequisites section).

export GC_PROMETHEUS_USERNAME=<my-grafana-cloud-prometheus-username>
export GC_API_KEY=<my-grafana-cloud-api-key>
export REMOTE_WRITE_ENDPOINT=<my-grafana-cloud-remote-write-endpoint>

kubectl create ns logging

kubectl create secret generic kubepromsecret \
  --from-literal=username=${GC_PROMETHEUS_USERNAME} \
  --from-literal=password=${GC_API_KEY} \
  -n logging

helm upgrade --install prometheus -n logging bitnami/kube-prometheus --version 6.6.0 -f - <<EOF
prometheus:
  remoteWrite:
  - url: ${REMOTE_WRITE_ENDPOINT}
    basicAuth:
      username:
        name: kubepromsecret
        key: username
      password:
        name: kubepromsecret
        key: password
EOF

Install Promtail as daemonset.

export GC_LOKI_USER=<my-grafana-cloud-loki-user>
export GC_API_KEY=<my-grafana-cloud-api-key>
export GC_LOKI_URL=<my-grafana-cloud-loki-url>

kubectl create secret generic kubelokisecret \
  --from-literal=username=${GC_LOKI_USER} \
  --from-literal=password=${GC_API_KEY} \
  -n logging

helm upgrade --install promtail -n logging grafana/promtail --version 3.8.1 -f - <<EOF
extraArgs:
  - -config.expand-env=true 
extraEnvFrom:
  - secretRef:
      name: kubelokisecret
config:
  logLevel: debug
  serverPort: 9080 
  lokiAddress: "https://${username}:${password}@${GC_LOKI_URL}/loki/api/v1/push" 
  snippets:
    pipelineStages:
      - match:
          selector: '{app="istio-ingressgateway"}'
          stages:
          # sample: accesslog [xxxx-xx-xxxxx:xxxxxxxxxx] "GET /category.html?tags=formal"
          # sample: accesslog [xxxx-xx-xxxxx:xxxxxxxxxx] "GET /category.html?tags=geek"
          - regex:
              expression: ^.*GET \/category.html\?tags=(?P<filter>geek)"
          - regex:
              expression: ^.*GET \/category.html\?tags=(?P<filter>formal)"
          - labels:
              filter:
          - metrics:
              filter:
                prefix: 'analytics_'
                type: Counter
                description: "Total count of filtered results"
                source: filter
                config:
                  action: inc               
serviceMonitor:
  enabled: true
  namespaceSelector: {}
  annotations: {}
  labels: {}
  interval: 10s
  scrapeTimeout: 5s
EOF

Port-forward both Prometheus and Promtail.

kubectl -n logging port-forward svc/prometheus-kube-prometheus-prometheus 9090:9090
kubectl -n logging port-forward ds/promtail 9080:9080

The Grafana dashboard

Let’s have a look at some pairs of socks by browsing through the catalog on the website while filtering on either “formal” or “geek” (this will create the required traffic).

In your browser open http://localhost:9080/metrics to consult Promtail metrics. Search for analytics_filter related entries.

On http://localhost:9090 Prometheus will visualize the metrics in the graph section when executing analytics_filter. These entries are forwarded to Grafana Cloud.

Side note: An alternate way of creating the setup in this post would be to use the Grafana Agent, which bundles the Prometheus discovery, WAL and remote_write capabilities without the local TSDB, and also bundles Promtail. Check out the Grafana Agent Quickstart guide.

Let’s consult the data on Grafana Cloud! On the Grafana Cloud Portal, you can log into Grafana to start using it by clicking “Log In.” On the Grafana General/Home page, you can create a new dashboard to visualize the generated metrics.

Let’s add a panel to the newly created dashboard by clicking “Add a new panel.”

Next, you define a query. From the “Data source” pulldown menu select grafanacloud-< your-grafana-cloud-stack-name >-prom to set Prometheus as data source.

Nearly done. Define your query and possibly give the panel a title. Here you will use:

sum(rate(analytics_filter[30s])) by (filter)

Click on “Apply” (top right corner of the page). Here you go!

You can add another panel to visualize the logs. Select grafanacloud-< your-grafana-cloud-stack-name >-logs to set Loki as the data source. Choose either Table or Logs as Visualization and define your query e.g. {filter=”geek”}.

Final thoughts

So the end result allows you to understand how both “formal” and “geek” socks are trending. The visualization of these metrics will surely help you to better understand what customers are looking for and guide you towards better business decisions that generate more revenue.

How to turn application logs into useful metrics with Gloo Edge and Grafana is a real use case story where Promtail is leveraged by Gloo Edge to find corner cases on one of its components: ExtAuth. The metric is used to signal and alert about a misconfiguration.

Knowing this approach, you can leverage the same setup to get metrics from your logs and not just to obtain some sort of analytics, but to understand better how your system works for DevOps purposes.