Skip to content

Commit 10612cb

Browse files
authored
Logs to files (#1396)
logs and debugging docs
1 parent 5030b3e commit 10612cb

File tree

7 files changed

+123
-8
lines changed

7 files changed

+123
-8
lines changed

book/src/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- [Configuration](./framework/configuration.md)
1818
- [Test Configuration](./framework/test_configuration_overrides.md)
1919
- [Exposing Components](framework/components/state.md)
20+
- [Debugging Tests](framework/components/debug.md)
2021
- [Components Cleanup](framework/components/cleanup.md)
2122
- [Components Caching](framework/components/caching.md)
2223
- [Mocking Services](framework/components/mocking.md)
@@ -28,7 +29,6 @@
2829
- [Logs](framework/observability/logs.md)
2930
- [Profiling](framework/observability/profiling.md)
3031
- [Traces]()
31-
- [Debugger]()
3232
- [Blockscout](framework/observability/blockscout.md)
3333
- [Components](framework/components/overview.md)
3434
- [Blockchains](framework/components/blockchains/overview.md)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Debugging Tests
2+
3+
All container logs are saved in a directory named `logs`, which will appear in the same directory where you ran the test after the test is completed.
4+
5+
For verifying your on-chain components, refer to the [Blockscout documentation](https://docs.blockscout.com/devs/verification/foundry-verification) on smart contract verification. This guide provides detailed instructions on uploading your ABI and verifying your contracts.
6+
7+
Use `CTF_LOG_LEVEL=trace|debug|info|warn` to debug the framework.
8+
9+
Use `RESTY_DEBUG=true` to debug any API calls.
10+
11+
Use `SETH_LOG_LEVEL=trace|debug|info|warn` to debug [Seth](../../libs/seth.md).
12+
13+
## Using Delve (TBD)
14+
15+
You can use [Delve]() inside your containers to debug aplications.
16+
17+
Build them with `go build -gcflags="all=-N -l" -o myapp` and use an example `Dockerfile`:
18+
```
19+
FROM golang:1.20
20+
21+
# Install Delve
22+
RUN go install github.com/go-delve/delve/cmd/dlv@latest
23+
24+
# Set working directory
25+
WORKDIR /app
26+
27+
# Copy the application binary and source code (if needed for debugging)
28+
COPY myapp /app/myapp
29+
COPY . /app
30+
31+
# Expose the port for Delve
32+
EXPOSE 40000
33+
34+
# Start Delve in headless mode for remote debugging
35+
ENTRYPOINT ["dlv", "exec", "./myapp", "--headless", "--listen=:40000", "--api-version=2", "--accept-multiclient"]
36+
37+
```
38+
39+
Adding `Delve` to all our components is WIP right now.
40+
41+
To expose `Delve` port follow this [guide](state.md).
42+
43+
44+

book/src/framework/observability/debugger.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

framework/.changeset/v0.2.11.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Save all containers logs by default
2+
- Add more docs about debug

framework/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ func Load[X any](t *testing.T) (*X, error) {
130130
t.Cleanup(func() {
131131
err := Store[X](input)
132132
require.NoError(t, err)
133+
err = WriteAllContainersLogs()
134+
require.NoError(t, err)
133135
})
134136
// TODO: not all the people have AWS access, sadly enough, uncomment when granted
135137
//if os.Getenv(EnvVarAWSSecretsManager) == "true" {

framework/docker.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"archive/tar"
55
"bytes"
66
"context"
7+
"encoding/binary"
78
"errors"
89
"fmt"
910
"github.com/docker/docker/api/types/container"
@@ -14,10 +15,15 @@ import (
1415
"io"
1516
"os"
1617
"os/exec"
18+
"path/filepath"
1719
"strings"
1820
"sync"
1921
)
2022

23+
const (
24+
DefaultCTFLogsDir = "logs"
25+
)
26+
2127
func IsDockerRunning() bool {
2228
cli, err := client.NewClientWithOpts(client.FromEnv)
2329
if err != nil {
@@ -223,3 +229,67 @@ func (dc *DockerClient) copyToContainer(containerID, sourceFile, targetPath stri
223229
}
224230
return nil
225231
}
232+
233+
// WriteAllContainersLogs writes all Docker container logs to the default logs directory
234+
func WriteAllContainersLogs() error {
235+
L.Info().Msg("Writing Docker containers logs")
236+
if _, err := os.Stat(DefaultCTFLogsDir); os.IsNotExist(err) {
237+
if err := os.MkdirAll(DefaultCTFLogsDir, 0755); err != nil {
238+
return fmt.Errorf("failed to create directory %s: %w", DefaultCTFLogsDir, err)
239+
}
240+
}
241+
provider, err := tc.NewDockerProvider()
242+
if err != nil {
243+
return fmt.Errorf("failed to create Docker provider: %w", err)
244+
}
245+
containers, err := provider.Client().ContainerList(context.Background(), container.ListOptions{All: true})
246+
if err != nil {
247+
return fmt.Errorf("failed to list Docker containers: %w", err)
248+
}
249+
250+
for _, containerInfo := range containers {
251+
containerName := containerInfo.Names[0]
252+
logOptions := container.LogsOptions{ShowStdout: true, ShowStderr: true}
253+
logs, err := provider.Client().ContainerLogs(context.Background(), containerInfo.ID, logOptions)
254+
if err != nil {
255+
L.Error().Err(err).Str("Container", containerName).Msg("failed to fetch logs for container")
256+
continue
257+
}
258+
logFilePath := filepath.Join(DefaultCTFLogsDir, fmt.Sprintf("%s.log", containerName))
259+
logFile, err := os.Create(logFilePath)
260+
if err != nil {
261+
L.Error().Err(err).Str("Container", containerName).Msg("failed to create container log file")
262+
continue
263+
}
264+
// Parse and write logs
265+
header := make([]byte, 8) // Docker stream header is 8 bytes
266+
for {
267+
_, err := io.ReadFull(logs, header)
268+
if err == io.EOF {
269+
break
270+
}
271+
if err != nil {
272+
L.Error().Err(err).Str("Container", containerName).Msg("failed to read log stream header")
273+
break
274+
}
275+
276+
// Extract log message size
277+
msgSize := binary.BigEndian.Uint32(header[4:8])
278+
279+
// Read the log message
280+
msg := make([]byte, msgSize)
281+
_, err = io.ReadFull(logs, msg)
282+
if err != nil {
283+
L.Error().Err(err).Str("Container", containerName).Msg("failed to read log message")
284+
break
285+
}
286+
287+
// Write the log message to the file
288+
if _, err := logFile.Write(msg); err != nil {
289+
L.Error().Err(err).Str("Container", containerName).Msg("failed to write log message to file")
290+
break
291+
}
292+
}
293+
}
294+
return nil
295+
}

wasp/examples/go.sum

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0
7373
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
7474
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
7575
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
76-
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
77-
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
76+
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
77+
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
7878
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
7979
github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA=
8080
github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
@@ -188,8 +188,7 @@ github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW
188188
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
189189
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
190190
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
191-
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
192-
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
191+
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
193192
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
194193
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
195194
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@@ -814,8 +813,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
814813
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
815814
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
816815
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
817-
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
818-
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
816+
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
819817
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
820818
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
821819
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=

0 commit comments

Comments
 (0)