Skip to content

Commit be0ae06

Browse files
committed
remove logstream. add function to dump Docker container logs to files
1 parent f3e38d0 commit be0ae06

File tree

19 files changed

+134
-2986
lines changed

19 files changed

+134
-2986
lines changed

book/src/lib.md

Lines changed: 9 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -252,38 +252,13 @@ Builder will read the location of chain configuration from env var named `PRIVAT
252252

253253
`net` is an instance of `blockchain.EVMNetwork`, which contains characteristics of the network and can be used to connect to it using an EVM client. `rpc` variable contains arrays of public and private RPC endpoints, where "private" means URL that's accessible from the same Docker network as the chain is running in.
254254

255-
# Using LogStream
255+
## Logs
256+
By default, we will save logs of all Docker containers running on the host machine, when the test ends (regardless whether it failed or succeeded). They will be available in the `./logs/<test-name><date>` directory. Same goes for dumping the databases of PostgresDBs
257+
used by the Chainlink nodes. These will be saves in the `./db_dumps/<test-name><date>` directory.
256258

257-
LogStream is a package that allows to connect to a Docker container and then flush logs to configured targets. Currently 3 targets are supported:
259+
## Loki and Grafana
258260

259-
- `file` - saves logs to a file in `./logs` folder
260-
- `loki` - sends logs to Loki
261-
- `in-memory` - stores logs in memory
262-
263-
It can be configured to use multiple targets at once. If no target is specified, it becomes a no-op.
264-
265-
LogStream has to be configured by passing an instance of `LoggingConfig` to the constructor.
266-
267-
When you connect a container LogStream will create a new consumer and start a detached goroutine that listens to logs emitted by that container and which reconnects and re-requests logs if listening fails for whatever reason. Retry limit and timeout can both be configured using functional options. In most cases one container should have one consumer, but it's possible to have multiple consumers for one container.
268-
269-
LogStream stores all logs in gob temporary file. To actually send/save them, you need to flush them. When you do it, LogStream will decode the file and send logs to configured targets. If log handling results in an error it won't be retried and processing of logs for given consumer will stop (if you think we should add a retry mechanism please let us know).
270-
271-
_Important:_ Flushing and accepting logs is blocking operation. That's because they both share the same cursor to temporary file and otherwise it's position would be racey and could result in mixed up logs.
272-
273-
## Configuration
274-
275-
Basic `LogStream` TOML configuration is following:
276-
277-
```toml
278-
[LogStream]
279-
log_targets=["file"]
280-
log_producer_timeout="10s"
281-
log_producer_retry_limit=10
282-
```
283-
284-
You can find it here: [logging_default.toml](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/config/tomls/logging_default.toml)
285-
286-
When using `in-memory` or `file` target no other configuration variables are required. When using `loki` target, following ones must be set:
261+
If you need to pass Loki or Grafana configuration to your tests you can do that by providing the following config:
287262

288263
```toml
289264
[Logging.Loki]
@@ -295,87 +270,13 @@ bearer_token_secret="bearer-token"
295270

296271
Also, do remember that different URL should be used when running in CI and everywhere else. In CI it should be a public endpoint, while in local environment it should be a private one.
297272

298-
If your test has a Grafana dashboard in order for the url to be correctly printed you should provide the following config:
273+
If your test has a Grafana dashboard you should provide the following config:
299274

300275
```toml
301276
[Logging.Grafana]
302-
url="http://grafana.somwhere.com/my_dashboard"
303-
```
304-
305-
## Initialisation
306-
307-
First you need to create a new instance:
308-
309-
```golang
310-
// t - instance of *testing.T (can be nil)
311-
// testConfig.Logging - pointer to logging part of TestConfig
312-
ls := logstream.NewLogStream(t, testConfig.Logging)
313-
```
314-
315-
## Listening to logs
316-
317-
If using `testcontainers-go` Docker containers it is recommended to use life cycle hooks for connecting and disconnecting LogStream from the container. You can do that when creating `ContainerRequest` in the following way:
318-
319-
```golang
320-
containerRequest := &tc.ContainerRequest{
321-
LifecycleHooks: []tc.ContainerLifecycleHooks{
322-
{PostStarts: []tc.ContainerHook{
323-
func(ctx context.Context, c tc.Container) error {
324-
if ls != nil {
325-
return n.ls.ConnectContainer(ctx, c, "custom-container-prefix-can-be-empty")
326-
}
327-
return nil
328-
},
329-
},
330-
PostStops: []tc.ContainerHook{
331-
func(ctx context.Context, c tc.Container) error {
332-
if ls != nil {
333-
return n.ls.DisconnectContainer(c)
334-
}
335-
return nil
336-
},
337-
}},
338-
},
339-
}
340-
```
341-
342-
You can print log location for each target using this function: `(m *LogStream) PrintLogTargetsLocations()`. For `file` target it will print relative folder path, for `loki` it will print URL of a Grafana Dashboard scoped to current execution and container ids. For `in-memory` target it's no-op.
343-
344-
It is recommended to shutdown LogStream at the end of your tests. Here's an example:
345-
346-
```golang
347-
t.Cleanup(func() {
348-
l.Warn().Msg("Shutting down Log Stream")
349-
350-
if t.Failed() || os.Getenv("TEST_LOG_COLLECT") == "true" {
351-
// we can't do much if this fails, so we just log the error
352-
_ = logStream.FlushLogsToTargets()
353-
// this will log log locations for each target (for file it will be a folder, for Loki Grafana dashboard -- remember to provide it's url in config!)
354-
logStream.PrintLogTargetsLocations()
355-
// this will save log locations in test summary, so that they can be easily accessed in GH's step summary
356-
logStream.SaveLogLocationInTestSummary()
357-
}
358-
359-
// we can't do much if this fails, so we just log the error
360-
_ = logStream.Shutdown(testcontext.Get(b.t))
361-
})
362-
```
363-
364-
or in a bit shorter way:
365-
366-
```golang
367-
t.Cleanup(func() {
368-
l.Warn().Msg("Shutting down Log Stream")
369-
370-
if t.Failed() || os.Getenv("TEST_LOG_COLLECT") == "true" {
371-
// this will log log locations for each target (for file it will be a folder, for Loki Grafana dashboard -- remember to provide it's url in config!)
372-
logStream.PrintLogTargetsLocations()
373-
// this will save log locations in test summary, so that they can be easily accessed in GH's step summary
374-
}
375-
376-
// we can't do much if this fails
377-
_ = logStream.FlushAndShutdown()
378-
})
277+
base_url="https://your-grafana-url"
278+
dashboard_url="/my-dashboard"
279+
dashboard_uid="my-dashboard-uid" # optional
379280
```
380281

381282
## Grouping test execution

book/src/lib/config/config.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ convert_to_toml_array() {
278278
}
279279
280280
selected_networks=$(convert_to_toml_array "$SELECTED_NETWORKS")
281-
log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS")
282281
283282
if [ -n "$PYROSCOPE_SERVER" ]; then
284283
pyroscope_enabled=true
@@ -292,12 +291,6 @@ else
292291
execution_layer="geth"
293292
fi
294293
295-
if [ -n "$TEST_LOG_COLLECT" ]; then
296-
test_log_collect=true
297-
else
298-
test_log_collect=false
299-
fi
300-
301294
cat << EOF > config.toml
302295
[Network]
303296
selected_networks=$selected_networks
@@ -312,13 +305,6 @@ server_url="$PYROSCOPE_SERVER"
312305
environment="$PYROSCOPE_ENVIRONMENT"
313306
key_secret="$PYROSCOPE_KEY"
314307
315-
[Logging]
316-
test_log_collect=$test_log_collect
317-
run_id="$RUN_ID"
318-
319-
[Logging.LogStream]
320-
log_targets=$log_targets
321-
322308
[Logging.Loki]
323309
tenant_id="$LOKI_TENANT_ID"
324310
url="$LOKI_URL"

lib/config/examples/example.toml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
# Example of full config with all fields
22
# General part
33
[Logging]
4-
# if set to true will save logs even if test did not fail
5-
test_log_collect=false
6-
7-
[Logging.LogStream]
8-
# supported targets: file, loki, in-memory. if empty no logs will be persistet
9-
log_targets=["file"]
10-
# context timeout for starting log producer and also time-frame for requesting logs
11-
log_producer_timeout="10s"
12-
# number of retries before log producer gives up and stops listening to logs
13-
log_producer_retry_limit=10
14-
154
[Logging.Loki]
165
tenant_id="tenant_id"
176
# full URL of Loki ingest endpoint
@@ -21,7 +10,6 @@ basic_auth_secret="loki-basic-auth"
2110
# only needed for cloud grafana
2211
bearer_token_secret="bearer_token"
2312

24-
# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set)
2513
[Logging.Grafana]
2614
# grafana url (trailing "/" will be stripped)
2715
base_url="http://grafana.url"

lib/config/logging.go

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,17 @@ import (
55

66
"github.com/pkg/errors"
77

8-
"github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain"
98
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/net"
109
)
1110

1211
type LoggingConfig struct {
13-
TestLogCollect *bool `toml:"test_log_collect,omitempty"`
14-
ShowHTMLCoverageReport *bool `toml:"show_html_coverage_report,omitempty"` // Show reports with go coverage data
15-
RunId *string `toml:"run_id,omitempty"`
16-
Loki *LokiConfig `toml:"-"`
17-
Grafana *GrafanaConfig `toml:"Grafana,omitempty"`
18-
LogStream *LogStreamConfig `toml:"LogStream,omitempty"`
12+
ShowHTMLCoverageReport *bool `toml:"show_html_coverage_report,omitempty"` // Show reports with go coverage data
13+
Loki *LokiConfig `toml:"-"`
14+
Grafana *GrafanaConfig `toml:"Grafana,omitempty"`
1915
}
2016

21-
// Validate executes config validation for LogStream, Grafana and Loki
17+
// Validate executes config validation for Grafana and Loki
2218
func (l *LoggingConfig) Validate() error {
23-
if l.LogStream != nil {
24-
if err := l.LogStream.Validate(); err != nil {
25-
return fmt.Errorf("invalid log stream config: %w", err)
26-
}
27-
}
28-
2919
if l.Grafana != nil {
3020
if err := l.Grafana.Validate(); err != nil {
3121
return fmt.Errorf("invalid grafana config: %w", err)
@@ -41,32 +31,6 @@ func (l *LoggingConfig) Validate() error {
4131
return nil
4232
}
4333

44-
type LogStreamConfig struct {
45-
LogTargets []string `toml:"log_targets"`
46-
LogProducerTimeout *blockchain.StrDuration `toml:"log_producer_timeout"`
47-
LogProducerRetryLimit *uint `toml:"log_producer_retry_limit"`
48-
}
49-
50-
// Validate checks that the log stream config is valid, which means that
51-
// log targets are valid and log producer timeout is greater than 0
52-
func (l *LogStreamConfig) Validate() error {
53-
if len(l.LogTargets) > 0 {
54-
for _, target := range l.LogTargets {
55-
if target != "loki" && target != "file" && target != "in-memory" {
56-
return fmt.Errorf("invalid log target %s", target)
57-
}
58-
}
59-
}
60-
61-
if l.LogProducerTimeout != nil {
62-
if l.LogProducerTimeout.Duration == 0 {
63-
return errors.New("log producer timeout must be greater than 0")
64-
}
65-
}
66-
67-
return nil
68-
}
69-
7034
type LokiConfig struct {
7135
TenantId *string `toml:"-"`
7236
Endpoint *string `toml:"-"`

lib/config/testconfig.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -54,36 +54,6 @@ type TestConfig struct {
5454
func (c *TestConfig) ReadFromEnvVar() error {
5555
logger := logging.GetTestLogger(nil)
5656

57-
testLogCollect := MustReadEnvVar_Boolean(E2E_TEST_LOG_COLLECT_ENV)
58-
if testLogCollect != nil {
59-
if c.Logging == nil {
60-
c.Logging = &LoggingConfig{}
61-
}
62-
logger.Debug().Msgf("Using %s env var to override Logging.TestLogCollect", E2E_TEST_LOG_COLLECT_ENV)
63-
c.Logging.TestLogCollect = testLogCollect
64-
}
65-
66-
loggingRunID := MustReadEnvVar_String(E2E_TEST_LOGGING_RUN_ID_ENV)
67-
if loggingRunID != "" {
68-
if c.Logging == nil {
69-
c.Logging = &LoggingConfig{}
70-
}
71-
logger.Debug().Msgf("Using %s env var to override Logging.RunID", E2E_TEST_LOGGING_RUN_ID_ENV)
72-
c.Logging.RunId = &loggingRunID
73-
}
74-
75-
logstreamLogTargets := MustReadEnvVar_Strings(E2E_TEST_LOG_STREAM_LOG_TARGETS_ENV, ",")
76-
if len(logstreamLogTargets) > 0 {
77-
if c.Logging == nil {
78-
c.Logging = &LoggingConfig{}
79-
}
80-
if c.Logging.LogStream == nil {
81-
c.Logging.LogStream = &LogStreamConfig{}
82-
}
83-
logger.Debug().Msgf("Using %s env var to override Logging.LogStream.LogTargets", E2E_TEST_LOG_STREAM_LOG_TARGETS_ENV)
84-
c.Logging.LogStream.LogTargets = logstreamLogTargets
85-
}
86-
8757
lokiTenantID := MustReadEnvVar_String(E2E_TEST_LOKI_TENANT_ID_ENV)
8858
if lokiTenantID != "" {
8959
if c.Logging == nil {

lib/config/tomls/logging_default.toml

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)