]> 91.132.146.200 Git - dolphin.git/commitdiff
adding php loki
authorBanana <mail@bananas-playground.net>
Tue, 14 May 2024 13:41:41 +0000 (15:41 +0200)
committerBanana <mail@bananas-playground.net>
Tue, 14 May 2024 13:41:41 +0000 (15:41 +0200)
Signed-off-by: Banana <mail@bananas-playground.net>
grafana-loki-metrics/index.php [new file with mode: 0644]
grafana-loki-metrics/loki.php [new file with mode: 0644]

diff --git a/grafana-loki-metrics/index.php b/grafana-loki-metrics/index.php
new file mode 100644 (file)
index 0000000..b27a0d4
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ *  dolphin. Collection of useful PHP skeletons.
+ *  Copyright (C) 2024 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
+ *
+ * You should have received a copy of the
+ * COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+ * along with this program.  If not, see http://www.sun.com/cddl/cddl.html
+ */
+
+/**
+ * This is an exmaple to show how to send custom logs/metrics
+ * to loki and use them in grafana
+ */
+
+# basic loki endpoint information
+const LOKI_HOST = "localhost";
+const LOKI_PORT = 3100;
+const LOKI_PUSH_API = "/loki/api/v1/push";
+# loki does not have protection
+# https://grafana.com/docs/loki/latest/operations/authentication/
+# this example does use basic auth
+# if you do not use it, comment both constants
+const LOKI_USER = "name";
+const LOKI_USER_PW = "pass";
+
+# Loki
+require_once 'loki.php';
+
+# see https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs for
+# data structure
+$Loki = new Loki(LOKI_HOST, LOKI_PORT, array("streamlabel1" => "value1", "streamlabel2" => "value2"));
+
+$Loki->log("log line text", array("structuredData" => "value"));
+$Loki->log("log line text", array("structuredData" => "value2"));
+
+# send the data to loki at the end to avoid and multiple calls and breaking
+# the process of the script.
+$Loki->send();
\ No newline at end of file
diff --git a/grafana-loki-metrics/loki.php b/grafana-loki-metrics/loki.php
new file mode 100644 (file)
index 0000000..cf264bb
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/**
+ *  dolphin. Collection of useful PHP skeletons.
+ *  Copyright (C) 2024 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
+ *
+ * You should have received a copy of the
+ * COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+ * along with this program.  If not, see http://www.sun.com/cddl/cddl.html
+ */
+
+
+/**
+ * Send log messages with optional structured data to Loki using the http api
+ * https://grafana.com/docs/loki/latest/reference/loki-http-api/
+ */
+class Loki {
+
+    /**
+     * @var string The host Loki runs on
+     */
+    private string $_host;
+
+    /**
+     * @var int The port number from the Loki installation
+     */
+    private int $_port;
+
+    /**
+     * @var array The stream lables. See Loki http api
+     */
+    private array $_stream = array();
+
+    /**
+     * @var array The log messages as an array to be send with send()
+     */
+    private array $_values = array();
+
+    /**
+     * @var string basic auth for endpoint
+     */
+    private string $_auth;
+
+    /**
+     * @param string $host Loki host
+     * @param int $port Loko host port
+     * @param array $stream Stream array with labels to send with
+     */
+    public function __construct(string $host, int $port, array $stream) {
+        $this->_stream = $stream;
+        $this->_host = $host;
+        $this->_port = $port;
+
+        if(defined("LOKI_USER") && !empty(LOKI_USER)) {
+            $this->_auth = base64_encode(LOKI_USER.":".LOKI_USER_PW);
+        }
+    }
+
+    /**
+     * Add a log message with optional structured data to the values to be send()
+     *
+     * @param string $msg The log message
+     * @param array $structuredData Additional structured data to be processed from Loki if configured
+     * @return void
+     */
+    public function log(string $msg, array $structuredData=array()): void {
+        $_nanosec = strval(shell_exec("date +%s%9N")-1);
+        if(!empty($structuredData)) {
+            $this->_values[] = array($_nanosec, $msg, $structuredData);
+        } else {
+            $this->_values[] = array($_nanosec, $msg);
+        }
+    }
+
+    /**
+     * Send the collected messages from log() to the loki installation
+     * The messages to be send will be resetted after
+     *
+     * @return string Non empty on error
+     */
+    public function send(): string {
+        $ret = "";
+
+        if(!LOKI_ENABLE) return $ret;
+
+        $data = array(
+            "streams" => array(
+                array(
+                    "stream" => $this->_stream,
+                    "values" => $this->_values
+                )
+            )
+        );
+
+        $data = json_encode($data);
+        $out = "POST ".LOKI_PUSH_API." HTTP/1.1\r\n";
+        $out .= "Host: $this->_host\r\n";
+        if(!empty($this->_auth)) {
+            $out .= "Authorization: Basic $this->_auth\r\n";
+        }
+        $out .= "Content-Type: application/json\r\n";
+        $out .= "Content-Length: ".strlen($data)."\r\n";
+        $out .= "Connection: Close\r\n\r\n";
+
+        $fp = fsockopen($this->_host, $this->_port, $errno, $errstr, 5);
+        if($fp) {
+            fwrite($fp, $out);
+            fwrite($fp, $data."\r\n");
+            fclose($fp);
+        } else {
+            $ret = $errno.' '.$errstr;
+        }
+
+        # reset
+        $this->_values = array();
+
+        return $ret;
+    }
+}