Commit 71d6154a authored by Jérome Perrin's avatar Jérome Perrin

Update Grafana

Update grafana, to use more recent golang. This also brings support of multi line logs in loki.

See merge request !921
parents b13ba7f7 3f116631
......@@ -14,6 +14,12 @@ parts =
[nodejs]
<= nodejs-8.9.4
[nodejs-14.16.0]
<= nodejs-base
openssl_location = ${openssl:location}
version = v14.16.0
md5sum = 7dc3666f407bf4e12a01ce1be2883d31
[nodejs-12.18.3]
<= nodejs-base
openssl_location = ${openssl:location}
......
......@@ -8,10 +8,10 @@ This is an experimental integration, mainly to evaluate these solutions.
See https://github.com/influxdata/telegraf to learn about plugins.
Useful plugins in this context are probably
[exec](https://github.com/influxdata/telegraf/tree/1.11.1/plugins/inputs/exec),
[logparser](https://github.com/influxdata/telegraf/tree/1.11.1/plugins/inputs/logparser)
[exec](https://github.com/influxdata/telegraf/tree/v1.17.3/plugins/inputs/exec),
[logparser](https://github.com/influxdata/telegraf/tree/v1.17.3/plugins/inputs/logparser)
or
[http](https://github.com/influxdata/telegraf/tree/1.11.1/plugins/inputs/http).
[http](https://github.com/influxdata/telegraf/tree/v1.17.3/plugins/inputs/http).
Telegraf will save in the `telegraf` database from the embedded influxdb server.
......
......@@ -15,7 +15,7 @@
[instance-profile]
filename = instance.cfg.in
md5sum = 13f4f3806522b265dd1912ff169d146d
md5sum = 3ccdd2299e759488545b62368c7a0b91
[influxdb-config-file]
filename = influxdb-config-file.cfg.in
......@@ -35,8 +35,8 @@ md5sum = 3aa0f1ed752b2a59ea2b5e7c1733daf3
[loki-config-file]
filename = loki-config-file.cfg.in
md5sum = 02ba5acf23fcf88f5594919f46838533
md5sum = ad2baf4599a937d7352034a41fa24814
[promtail-config-file]
filename = promtail-config-file.cfg.in
md5sum = c77788d0a3cc654ad9393eb4b1f31e94
md5sum = c8c9d815dd7b427788c066f041f04573
......@@ -20,22 +20,22 @@ revision = 1f7c19e5f5
<= go-git-package
go.importpath = github.com/grafana/grafana
repository = https://github.com/grafana/grafana
revision = v6.3.0-0-g830da0fda0
revision = v7.4.3-0-g010f20c1c8
[go_github.com_grafana_loki]
<= go-git-package
go.importpath = github.com/grafana/loki
repository = https://github.com/grafana/loki
revision = v0.3.0-0-gc673380bb3
revision = v2.1.0-188-g877f524c36
[go_github.com_influxdata_influxdb]
<= go-git-package
go.importpath = github.com/influxdata/influxdb
repository = https://github.com/influxdata/influxdb
revision = v1.7.8rc1-0-ga7afa2ecf1
revision = v1.8.4-0-gbc8ec4384e
[go_github.com_influxdata_telegraf]
<= go-git-package
go.importpath = github.com/influxdata/telegraf
repository = https://github.com/influxdata/telegraf
revision = 1.11.1-0-gf91de60d37
revision = v1.17.3-0-g24a552b90b
......@@ -132,7 +132,7 @@ command-line =
bash -c "{{ influx_bin }} \
-username ${influxdb:auth-username} \
-password ${influxdb:auth-password} \
-host ${influxdb:host} \
-host [${influxdb:host}] \
-port ${influxdb:http-port} \
-unsafeSsl \
-ssl \
......@@ -219,6 +219,7 @@ storage-boltdb-dir = ${directory:loki-storage-boltdb-dir}
storage-filesystem-dir = ${directory:loki-storage-filesystem-dir}
ip = ${instance-parameter:ipv4-random}
port = 3100
grpc-port = 9095
url = http://${:ip}:${:port}
......@@ -238,9 +239,10 @@ command-line =
wrapper-path = ${directory:service}/promtail
dir = ${directory:promtail-dir}
http_port = 19080
http-port = 19080
grpc-port = 19095
ip = ${instance-parameter:ipv4-random}
url = http://${:ip}:${:http_port}
url = http://${:ip}:${:http-port}
[promtail-config-file]
<= config-file
......@@ -252,7 +254,7 @@ context =
[promtail-listen-promise]
<= check-port-listening-promise
hostname= ${promtail:ip}
port = ${promtail:http_port}
port = ${promtail:http-port}
......
auth_enabled: false
server:
http_listen_address: {{ loki['ip'] }}
http_listen_port: {{ loki['port'] }}
grpc_listen_address: {{ loki['ip'] }}
grpc_listen_port: {{ loki['grpc-port'] }}
ingester:
lifecycler:
......
# https://github.com/grafana/loki/blob/master/docs/logentry/processing-log-lines.md
server:
http_listen_port: {{ promtail['http_port'] }}
# XXX this external_url does not work ... promtail still listen on all IPs
http_listen_address: {{ promtail['ip'] }}
http_listen_port: {{ promtail['http-port'] }}
grpc_listen_address: {{ promtail['ip'] }}
grpc_listen_port: {{ promtail['grpc-port'] }}
external_url: {{ promtail['url'] }}
grpc_listen_port: 0
positions:
filename: {{ promtail['dir'] }}/positions.yaml
......
......@@ -22,12 +22,14 @@ parts =
loki-config-file
promtail-config-file
[python]
part = python3
[nodejs]
<= nodejs-10.6.0
<= nodejs-14.16.0
[yarn]
<= yarn-1.16.0
<= yarn-1.22.10
[gowork]
# All the softwares installed in the go workspace have "non standard" installation
......@@ -44,7 +46,7 @@ loki-bin = ${:bin}/loki
promtail-bin = ${:bin}/promtail
# use recent go
golang = ${golang1.12:location}
golang = ${golang1.16:location}
[gowork.goinstall]
command = :
......@@ -60,8 +62,7 @@ depends =
command = bash -c ". ${gowork:env.sh} && \
go install -v github.com/golang/dep/cmd/dep && \
cd ${gowork:directory}/src/github.com/influxdata/influxdb && \
dep ensure && \
go install ./cmd/..."
go install ./..."
update-command =
[telegraf-install]
......@@ -75,14 +76,17 @@ update-command =
[grafana-install]
<= gowork.goinstall
# yarn and go run build.go needs our nodejs in $PATH
command = bash -c "export PATH=${nodejs:location}/bin/:$PATH && \
. ${gowork:env.sh} && \
command = bash -c ". ${gowork:env.sh} && \
cd ${gowork:directory}/src/github.com/grafana/grafana && \
go run build.go setup && \
go run build.go build && \
${yarn:location}/bin/yarn install --pure-lockfile && \
${nodejs:location}/bin/npm run build"
${yarn:location}/bin/yarn run build && \
${yarn:location}/bin/yarn run plugins:build-bundled && \
# Cleanup yarn and Cypress caches
rm -rf ${buildout:directory}/.cache/Cypress/ && \
rm -rf ${buildout:directory}/.cache/yarn/
"
update-command =
[loki-install]
......
......@@ -25,12 +25,13 @@
#
##############################################################################
import os
import textwrap
import logging
import os
import tempfile
import textwrap
import time
import psutil
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
......@@ -44,11 +45,11 @@ setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
class GrafanaTestCase(SlapOSInstanceTestCase):
"""Base test case for grafana.
Since the instances takes timte to start and stop,
we increate as lot the number of retries.
Since the instances takes time to start and stop,
we increase the number of retries.
"""
instance_max_retry = 50
report_max_retry = 30
instance_max_retry = 30
class TestGrafana(GrafanaTestCase):
......@@ -144,21 +145,27 @@ class TestLoki(GrafanaTestCase):
r'''
- job_name: {cls.__name__}
pipeline_stages:
- regex:
expression: "^(?P<timestamp>.*) - (?P<name>\\S+) - (?P<level>\\S+) - (?P<message>.*)"
- timestamp:
format: 2006-01-02T15:04:05Z00:00
source: timestamp
- labels:
level:
name:
- match:
selector: '{{job="{cls.__name__}"}}'
stages:
- multiline:
firstline: '^\d{{4}}-\d{{2}}-\d{{2}}\s\d{{1,2}}\:\d{{2}}\:\d{{2}}\,\d{{3}}'
max_wait_time: 3s
- regex:
expression: '^(?P<timestamp>.*) - (?P<name>\S+) - (?P<level>\S+) - (?P<message>.*)'
- timestamp:
format: 2006-01-02T15:04:05Z00:00
source: timestamp
- labels:
level:
name:
static_configs:
- targets:
- localhost
labels:
job: {cls.__name__}
__path__: {cls._logfile.name}
''').format(**locals())
- targets:
- localhost
labels:
job: {cls.__name__}
__path__: {cls._logfile.name}
''').format(**locals())
}
@classmethod
......@@ -180,6 +187,7 @@ class TestLoki(GrafanaTestCase):
# create a logger logging to the file that we have
# configured in instance parameter.
test_logger = logging.getLogger(self.id())
test_logger.propagate = False
test_logger.setLevel(logging.INFO)
test_handler = logging.FileHandler(filename=self._logfile.name)
test_handler.setFormatter(
......@@ -189,16 +197,25 @@ class TestLoki(GrafanaTestCase):
test_logger.info("testing message")
test_logger.info("testing another message")
test_logger.warning("testing warn")
# log an exception, which will be multi line in log file.
def nested1():
def nested2():
raise ValueError('boom')
nested2()
try:
nested1()
except ValueError:
test_logger.exception("testing exception")
# Check our messages have been ingested
# we retry a few times, because there's a short delay until messages are
# ingested and returned.
for i in range(10):
for i in range(60):
resp = requests.get(
'{self.loki_url}/api/prom/query?query={{job="TestLoki"}}'.format(
**locals()),
verify=False).json()
if not resp:
if len(resp.get('streams', [])) < 3:
time.sleep(0.5 * i)
continue
......@@ -220,9 +237,83 @@ class TestLoki(GrafanaTestCase):
line for line in info_stream['entries']
if "testing another message" in line['line']
])
error_stream_list = [stream for stream in resp['streams'] if 'level="ERROR"' in stream['labels']]
self.assertEqual(1, len(error_stream_list), resp['streams'])
error_stream, = error_stream_list
line, = [line['line'] for line in error_stream['entries']]
# this entry is multi-line
self.assertIn('testing exception\nTraceback (most recent call last):\n', line)
self.assertIn('ValueError: boom', line)
# The labels we have configued are also available
resp = requests.get(
'{self.loki_url}/api/prom/label'.format(**locals()),
verify=False).json()
self.assertIn('level', resp['values'])
self.assertIn('name', resp['values'])
class TestListenInPartition(GrafanaTestCase):
def setUp(self):
with self.slap.instance_supervisor_rpc as supervisor:
all_process_info = supervisor.getAllProcessInfo()
self.process_dict = {
p['name'].replace('-on-watch', ''): psutil.Process(p['pid'])
for p in all_process_info if p['name'] != 'watchdog'
}
def test_grafana_listen(self):
self.assertEqual(
[
c.laddr for c in self.process_dict['grafana'].connections()
if c.status == 'LISTEN'
],
[(self._ipv6_address, 8180)],
)
def test_influxdb_listen(self):
self.assertEqual(
sorted([
c.laddr for c in self.process_dict['influxdb'].connections()
if c.status == 'LISTEN'
]),
[
(self._ipv4_address, 8088),
(self._ipv6_address, 8086),
],
)
def test_telegraph_listen(self):
self.assertEqual(
[
c.laddr for c in self.process_dict['telegraf'].connections()
if c.status == 'LISTEN'
],
[],
)
def test_loki_listen(self):
self.assertEqual(
sorted([
c.laddr for c in self.process_dict['loki'].connections()
if c.status == 'LISTEN'
]),
[
(self._ipv4_address, 3100),
(self._ipv4_address, 9095),
],
)
def test_promtail_listen(self):
self.assertEqual(
sorted([
c.laddr for c in self.process_dict['promtail'].connections()
if c.status == 'LISTEN'
]),
[
(self._ipv4_address, 19080),
(self._ipv4_address, 19095),
],
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment