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 nexedi/slapos!921
parents b13ba7f7 3f116631
Pipeline #13987 failed with stage
in 0 seconds
...@@ -14,6 +14,12 @@ parts = ...@@ -14,6 +14,12 @@ parts =
[nodejs] [nodejs]
<= nodejs-8.9.4 <= 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-12.18.3]
<= nodejs-base <= nodejs-base
openssl_location = ${openssl:location} openssl_location = ${openssl:location}
......
...@@ -8,10 +8,10 @@ This is an experimental integration, mainly to evaluate these solutions. ...@@ -8,10 +8,10 @@ This is an experimental integration, mainly to evaluate these solutions.
See https://github.com/influxdata/telegraf to learn about plugins. See https://github.com/influxdata/telegraf to learn about plugins.
Useful plugins in this context are probably Useful plugins in this context are probably
[exec](https://github.com/influxdata/telegraf/tree/1.11.1/plugins/inputs/exec), [exec](https://github.com/influxdata/telegraf/tree/v1.17.3/plugins/inputs/exec),
[logparser](https://github.com/influxdata/telegraf/tree/1.11.1/plugins/inputs/logparser) [logparser](https://github.com/influxdata/telegraf/tree/v1.17.3/plugins/inputs/logparser)
or 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. Telegraf will save in the `telegraf` database from the embedded influxdb server.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
[instance-profile] [instance-profile]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = 13f4f3806522b265dd1912ff169d146d md5sum = 3ccdd2299e759488545b62368c7a0b91
[influxdb-config-file] [influxdb-config-file]
filename = influxdb-config-file.cfg.in filename = influxdb-config-file.cfg.in
...@@ -35,8 +35,8 @@ md5sum = 3aa0f1ed752b2a59ea2b5e7c1733daf3 ...@@ -35,8 +35,8 @@ md5sum = 3aa0f1ed752b2a59ea2b5e7c1733daf3
[loki-config-file] [loki-config-file]
filename = loki-config-file.cfg.in filename = loki-config-file.cfg.in
md5sum = 02ba5acf23fcf88f5594919f46838533 md5sum = ad2baf4599a937d7352034a41fa24814
[promtail-config-file] [promtail-config-file]
filename = promtail-config-file.cfg.in filename = promtail-config-file.cfg.in
md5sum = c77788d0a3cc654ad9393eb4b1f31e94 md5sum = c8c9d815dd7b427788c066f041f04573
...@@ -20,22 +20,22 @@ revision = 1f7c19e5f5 ...@@ -20,22 +20,22 @@ revision = 1f7c19e5f5
<= go-git-package <= go-git-package
go.importpath = github.com/grafana/grafana go.importpath = github.com/grafana/grafana
repository = https://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_github.com_grafana_loki]
<= go-git-package <= go-git-package
go.importpath = github.com/grafana/loki go.importpath = github.com/grafana/loki
repository = https://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_github.com_influxdata_influxdb]
<= go-git-package <= go-git-package
go.importpath = github.com/influxdata/influxdb go.importpath = github.com/influxdata/influxdb
repository = https://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_github.com_influxdata_telegraf]
<= go-git-package <= go-git-package
go.importpath = github.com/influxdata/telegraf go.importpath = github.com/influxdata/telegraf
repository = https://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 = ...@@ -132,7 +132,7 @@ command-line =
bash -c "{{ influx_bin }} \ bash -c "{{ influx_bin }} \
-username ${influxdb:auth-username} \ -username ${influxdb:auth-username} \
-password ${influxdb:auth-password} \ -password ${influxdb:auth-password} \
-host ${influxdb:host} \ -host [${influxdb:host}] \
-port ${influxdb:http-port} \ -port ${influxdb:http-port} \
-unsafeSsl \ -unsafeSsl \
-ssl \ -ssl \
...@@ -219,6 +219,7 @@ storage-boltdb-dir = ${directory:loki-storage-boltdb-dir} ...@@ -219,6 +219,7 @@ storage-boltdb-dir = ${directory:loki-storage-boltdb-dir}
storage-filesystem-dir = ${directory:loki-storage-filesystem-dir} storage-filesystem-dir = ${directory:loki-storage-filesystem-dir}
ip = ${instance-parameter:ipv4-random} ip = ${instance-parameter:ipv4-random}
port = 3100 port = 3100
grpc-port = 9095
url = http://${:ip}:${:port} url = http://${:ip}:${:port}
...@@ -238,9 +239,10 @@ command-line = ...@@ -238,9 +239,10 @@ command-line =
wrapper-path = ${directory:service}/promtail wrapper-path = ${directory:service}/promtail
dir = ${directory:promtail-dir} dir = ${directory:promtail-dir}
http_port = 19080 http-port = 19080
grpc-port = 19095
ip = ${instance-parameter:ipv4-random} ip = ${instance-parameter:ipv4-random}
url = http://${:ip}:${:http_port} url = http://${:ip}:${:http-port}
[promtail-config-file] [promtail-config-file]
<= config-file <= config-file
...@@ -252,7 +254,7 @@ context = ...@@ -252,7 +254,7 @@ context =
[promtail-listen-promise] [promtail-listen-promise]
<= check-port-listening-promise <= check-port-listening-promise
hostname= ${promtail:ip} hostname= ${promtail:ip}
port = ${promtail:http_port} port = ${promtail:http-port}
......
auth_enabled: false auth_enabled: false
server: server:
http_listen_address: {{ loki['ip'] }}
http_listen_port: {{ loki['port'] }} http_listen_port: {{ loki['port'] }}
grpc_listen_address: {{ loki['ip'] }}
grpc_listen_port: {{ loki['grpc-port'] }}
ingester: ingester:
lifecycler: lifecycler:
......
# https://github.com/grafana/loki/blob/master/docs/logentry/processing-log-lines.md
server: server:
http_listen_port: {{ promtail['http_port'] }} http_listen_address: {{ promtail['ip'] }}
# XXX this external_url does not work ... promtail still listen on all IPs http_listen_port: {{ promtail['http-port'] }}
grpc_listen_address: {{ promtail['ip'] }}
grpc_listen_port: {{ promtail['grpc-port'] }}
external_url: {{ promtail['url'] }} external_url: {{ promtail['url'] }}
grpc_listen_port: 0
positions: positions:
filename: {{ promtail['dir'] }}/positions.yaml filename: {{ promtail['dir'] }}/positions.yaml
......
...@@ -22,12 +22,14 @@ parts = ...@@ -22,12 +22,14 @@ parts =
loki-config-file loki-config-file
promtail-config-file promtail-config-file
[python]
part = python3
[nodejs] [nodejs]
<= nodejs-10.6.0 <= nodejs-14.16.0
[yarn] [yarn]
<= yarn-1.16.0 <= yarn-1.22.10
[gowork] [gowork]
# All the softwares installed in the go workspace have "non standard" installation # All the softwares installed in the go workspace have "non standard" installation
...@@ -44,7 +46,7 @@ loki-bin = ${:bin}/loki ...@@ -44,7 +46,7 @@ loki-bin = ${:bin}/loki
promtail-bin = ${:bin}/promtail promtail-bin = ${:bin}/promtail
# use recent go # use recent go
golang = ${golang1.12:location} golang = ${golang1.16:location}
[gowork.goinstall] [gowork.goinstall]
command = : command = :
...@@ -60,8 +62,7 @@ depends = ...@@ -60,8 +62,7 @@ depends =
command = bash -c ". ${gowork:env.sh} && \ command = bash -c ". ${gowork:env.sh} && \
go install -v github.com/golang/dep/cmd/dep && \ go install -v github.com/golang/dep/cmd/dep && \
cd ${gowork:directory}/src/github.com/influxdata/influxdb && \ cd ${gowork:directory}/src/github.com/influxdata/influxdb && \
dep ensure && \ go install ./..."
go install ./cmd/..."
update-command = update-command =
[telegraf-install] [telegraf-install]
...@@ -75,14 +76,17 @@ update-command = ...@@ -75,14 +76,17 @@ update-command =
[grafana-install] [grafana-install]
<= gowork.goinstall <= gowork.goinstall
# yarn and go run build.go needs our nodejs in $PATH command = bash -c ". ${gowork:env.sh} && \
command = bash -c "export PATH=${nodejs:location}/bin/:$PATH && \
. ${gowork:env.sh} && \
cd ${gowork:directory}/src/github.com/grafana/grafana && \ cd ${gowork:directory}/src/github.com/grafana/grafana && \
go run build.go setup && \ go run build.go setup && \
go run build.go build && \ go run build.go build && \
${yarn:location}/bin/yarn install --pure-lockfile && \ ${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 = update-command =
[loki-install] [loki-install]
......
...@@ -25,12 +25,13 @@ ...@@ -25,12 +25,13 @@
# #
############################################################################## ##############################################################################
import os
import textwrap
import logging import logging
import os
import tempfile import tempfile
import textwrap
import time import time
import psutil
import requests import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
...@@ -44,11 +45,11 @@ setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass( ...@@ -44,11 +45,11 @@ setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
class GrafanaTestCase(SlapOSInstanceTestCase): class GrafanaTestCase(SlapOSInstanceTestCase):
"""Base test case for grafana. """Base test case for grafana.
Since the instances takes timte to start and stop, Since the instances takes time to start and stop,
we increate as lot the number of retries. we increase the number of retries.
""" """
instance_max_retry = 50
report_max_retry = 30 report_max_retry = 30
instance_max_retry = 30
class TestGrafana(GrafanaTestCase): class TestGrafana(GrafanaTestCase):
...@@ -144,21 +145,27 @@ class TestLoki(GrafanaTestCase): ...@@ -144,21 +145,27 @@ class TestLoki(GrafanaTestCase):
r''' r'''
- job_name: {cls.__name__} - job_name: {cls.__name__}
pipeline_stages: pipeline_stages:
- regex: - match:
expression: "^(?P<timestamp>.*) - (?P<name>\\S+) - (?P<level>\\S+) - (?P<message>.*)" selector: '{{job="{cls.__name__}"}}'
- timestamp: stages:
format: 2006-01-02T15:04:05Z00:00 - multiline:
source: timestamp firstline: '^\d{{4}}-\d{{2}}-\d{{2}}\s\d{{1,2}}\:\d{{2}}\:\d{{2}}\,\d{{3}}'
- labels: max_wait_time: 3s
level: - regex:
name: 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: static_configs:
- targets: - targets:
- localhost - localhost
labels: labels:
job: {cls.__name__} job: {cls.__name__}
__path__: {cls._logfile.name} __path__: {cls._logfile.name}
''').format(**locals()) ''').format(**locals())
} }
@classmethod @classmethod
...@@ -180,6 +187,7 @@ class TestLoki(GrafanaTestCase): ...@@ -180,6 +187,7 @@ class TestLoki(GrafanaTestCase):
# create a logger logging to the file that we have # create a logger logging to the file that we have
# configured in instance parameter. # configured in instance parameter.
test_logger = logging.getLogger(self.id()) test_logger = logging.getLogger(self.id())
test_logger.propagate = False
test_logger.setLevel(logging.INFO) test_logger.setLevel(logging.INFO)
test_handler = logging.FileHandler(filename=self._logfile.name) test_handler = logging.FileHandler(filename=self._logfile.name)
test_handler.setFormatter( test_handler.setFormatter(
...@@ -189,16 +197,25 @@ class TestLoki(GrafanaTestCase): ...@@ -189,16 +197,25 @@ class TestLoki(GrafanaTestCase):
test_logger.info("testing message") test_logger.info("testing message")
test_logger.info("testing another message") test_logger.info("testing another message")
test_logger.warning("testing warn") 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 # Check our messages have been ingested
# we retry a few times, because there's a short delay until messages are # we retry a few times, because there's a short delay until messages are
# ingested and returned. # ingested and returned.
for i in range(10): for i in range(60):
resp = requests.get( resp = requests.get(
'{self.loki_url}/api/prom/query?query={{job="TestLoki"}}'.format( '{self.loki_url}/api/prom/query?query={{job="TestLoki"}}'.format(
**locals()), **locals()),
verify=False).json() verify=False).json()
if not resp: if len(resp.get('streams', [])) < 3:
time.sleep(0.5 * i) time.sleep(0.5 * i)
continue continue
...@@ -220,9 +237,83 @@ class TestLoki(GrafanaTestCase): ...@@ -220,9 +237,83 @@ class TestLoki(GrafanaTestCase):
line for line in info_stream['entries'] line for line in info_stream['entries']
if "testing another message" in line['line'] 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 # The labels we have configued are also available
resp = requests.get( resp = requests.get(
'{self.loki_url}/api/prom/label'.format(**locals()), '{self.loki_url}/api/prom/label'.format(**locals()),
verify=False).json() verify=False).json()
self.assertIn('level', resp['values']) self.assertIn('level', resp['values'])
self.assertIn('name', 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