<commit_before>diff --git a/Koha/Util/InfluxDB.pm b/Koha/Util/InfluxDB.pm
new file mode 100644
index 0000000..8f878b1 100644
--- a/Koha/Util/InfluxDB.pm
+++ b/Koha/Util/InfluxDB.pm
@@ -0,0 +1,49 @@
+use strict;
+use warnings;
+
+package Koha::Util::InfluxDB;
+use Data::Dumper;
+use Sys::Hostname;
+use IO::Socket;
+use base 'Exporter';
+
+our @EXPORTER_OK = qw/metric/;
+
+our $TAGS;
+our $server;
+our $port = 8089;
+our $sock;
+
+sub init {
+    $server or die "set \$".__PACKAGE__."::server first";
+    $sock = IO::Socket::INET->new(
+        Proto => 'udp',
+        PeerPort => $port,
+        PeerAddr => $server,
+    );
+
+    $TAGS = {
+        hostname => hostname,
+    };
+    while(my ($k,$v) = each %ENV) {
+        $k =~ m{^METRICS?_(\S+)$} or next;
+        $TAGS->{lc($1)}=$v;
+    }
+
+}
+
+# example metric(plack => elapsed => 0.34 => { path => '/foo/bar.pl' });
+sub metric {
+    $sock or init();
+    my ($app, $name, $value, $tags) = @_;
+
+    $app // die "you must specify a metric";
+    $name // die "you must specify a name";
+
+    my $all_tags = {%$TAGS, %$tags};
+    my $ln = join(',', $app, map { "$_=$all_tags->{$_}"; } keys %$all_tags)." $name=$value";
+
+    $sock->send($ln) or warn "metric send error: $!";
+}
+
+1;
diff --git a/debian/templates/plack.psgi b/debian/templates/plack.psgi
index 3538b9a..fdb2529 100644<commit_msg>InfluxDB: don't fail if metrics host is not resolvable<commit_after>diff --git a/Koha/Util/InfluxDB.pm b/Koha/Util/InfluxDB.pm
new file mode 100644
index 0000000..e5db2cc 100644
--- a/Koha/Util/InfluxDB.pm
+++ b/Koha/Util/InfluxDB.pm
@@ -0,0 +1,50 @@
+use strict;
+use warnings;
+
+package Koha::Util::InfluxDB;
+use Data::Dumper;
+use Sys::Hostname;
+use IO::Socket;
+use base 'Exporter';
+
+our @EXPORTER_OK = qw/metric/;
+
+our $TAGS;
+our $server;
+our $port = 8089;
+our $sock;
+
+sub init {
+    $server or die "set \$".__PACKAGE__."::server first";
+    $sock = IO::Socket::INET->new(
+        Proto => 'udp',
+        PeerPort => $port,
+        PeerAddr => $server,
+    );
+
+    $TAGS = {
+        hostname => hostname,
+    };
+    while(my ($k,$v) = each %ENV) {
+        $k =~ m{^METRICS?_(\S+)$} or next;
+        $TAGS->{lc($1)}=$v;
+    }
+
+}
+
+# example metric(plack => elapsed => 0.34 => { path => '/foo/bar.pl' });
+sub metric {
+    $TAGS or init();
+    $sock or return;
+    my ($app, $name, $value, $tags) = @_;
+
+    $app // die "you must specify a metric";
+    $name // die "you must specify a name";
+
+    my $all_tags = {%$TAGS, %$tags};
+    my $ln = join(',', $app, map { "$_=$all_tags->{$_}"; } keys %$all_tags)." $name=$value";
+
+    $sock->send($ln) or warn "metric send error: $!";
+}
+
+1;
diff --git a/debian/templates/plack.psgi b/debian/templates/plack.psgi
index 3538b9a..fdb2529 100644
{'fraction_non_alphanumeric': 0.2282958199356913, 'fraction_numerical': 0.03679885673454805, 'mean_word_length': 3.0816326530612246, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3829994', 'n_tokens_mistral': 1286, 'n_tokens_neox': 1170, 'n_words': 264}