Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logs to files #1396

Merged
merged 11 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [Configuration](./framework/configuration.md)
- [Test Configuration](./framework/test_configuration_overrides.md)
- [Exposing Components](framework/components/state.md)
- [Debugging Tests](framework/components/debug.md)
- [Components Cleanup](framework/components/cleanup.md)
- [Components Caching](framework/components/caching.md)
- [Mocking Services](framework/components/mocking.md)
Expand All @@ -28,7 +29,6 @@
- [Logs](framework/observability/logs.md)
- [Profiling](framework/observability/profiling.md)
- [Traces]()
- [Debugger]()
- [Blockscout](framework/observability/blockscout.md)
- [Components](framework/components/overview.md)
- [Blockchains](framework/components/blockchains/overview.md)
Expand Down
44 changes: 44 additions & 0 deletions book/src/framework/components/debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Debugging Tests

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.

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.

Use `CTF_LOG_LEVEL=trace|debug|info|warn` to debug the framework.

Use `RESTY_DEBUG=true` to debug any API calls.

Use `SETH_LOG_LEVEL=trace|debug|info|warn` to debug [Seth](../../libs/seth.md).

## Using Delve (TBD)

You can use [Delve]() inside your containers to debug aplications.

Build them with `go build -gcflags="all=-N -l" -o myapp` and use an example `Dockerfile`:
```
FROM golang:1.20

# Install Delve
RUN go install github.com/go-delve/delve/cmd/dlv@latest

# Set working directory
WORKDIR /app

# Copy the application binary and source code (if needed for debugging)
COPY myapp /app/myapp
COPY . /app

# Expose the port for Delve
EXPOSE 40000

# Start Delve in headless mode for remote debugging
ENTRYPOINT ["dlv", "exec", "./myapp", "--headless", "--listen=:40000", "--api-version=2", "--accept-multiclient"]

```

Adding `Delve` to all our components is WIP right now.

To expose `Delve` port follow this [guide](state.md).



1 change: 0 additions & 1 deletion book/src/framework/observability/debugger.md

This file was deleted.

2 changes: 2 additions & 0 deletions framework/.changeset/v0.2.11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Save all containers logs by default
- Add more docs about debug
2 changes: 2 additions & 0 deletions framework/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ func Load[X any](t *testing.T) (*X, error) {
t.Cleanup(func() {
err := Store[X](input)
require.NoError(t, err)
err = WriteAllContainersLogs()
require.NoError(t, err)
})
// TODO: not all the people have AWS access, sadly enough, uncomment when granted
//if os.Getenv(EnvVarAWSSecretsManager) == "true" {
Expand Down
70 changes: 70 additions & 0 deletions framework/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"archive/tar"
"bytes"
"context"
"encoding/binary"
"errors"
"fmt"
"github.com/docker/docker/api/types/container"
Expand All @@ -14,10 +15,15 @@ import (
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
)

const (
DefaultCTFLogsDir = "logs"
)

func IsDockerRunning() bool {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
Expand Down Expand Up @@ -223,3 +229,67 @@ func (dc *DockerClient) copyToContainer(containerID, sourceFile, targetPath stri
}
return nil
}

// WriteAllContainersLogs writes all Docker container logs to the default logs directory
func WriteAllContainersLogs() error {
L.Info().Msg("Writing Docker containers logs")
if _, err := os.Stat(DefaultCTFLogsDir); os.IsNotExist(err) {
if err := os.MkdirAll(DefaultCTFLogsDir, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", DefaultCTFLogsDir, err)
}
}
provider, err := tc.NewDockerProvider()
if err != nil {
return fmt.Errorf("failed to create Docker provider: %w", err)
}
containers, err := provider.Client().ContainerList(context.Background(), container.ListOptions{All: true})
if err != nil {
return fmt.Errorf("failed to list Docker containers: %w", err)
}

for _, containerInfo := range containers {
containerName := containerInfo.Names[0]
logOptions := container.LogsOptions{ShowStdout: true, ShowStderr: true}
logs, err := provider.Client().ContainerLogs(context.Background(), containerInfo.ID, logOptions)
if err != nil {
L.Error().Err(err).Str("Container", containerName).Msg("failed to fetch logs for container")
continue
}
logFilePath := filepath.Join(DefaultCTFLogsDir, fmt.Sprintf("%s.log", containerName))
logFile, err := os.Create(logFilePath)
if err != nil {
L.Error().Err(err).Str("Container", containerName).Msg("failed to create container log file")
continue
}
// Parse and write logs
header := make([]byte, 8) // Docker stream header is 8 bytes
for {
_, err := io.ReadFull(logs, header)
if err == io.EOF {
break
}
if err != nil {
L.Error().Err(err).Str("Container", containerName).Msg("failed to read log stream header")
break
}

// Extract log message size
msgSize := binary.BigEndian.Uint32(header[4:8])

// Read the log message
msg := make([]byte, msgSize)
_, err = io.ReadFull(logs, msg)
if err != nil {
L.Error().Err(err).Str("Container", containerName).Msg("failed to read log message")
break
}

// Write the log message to the file
if _, err := logFile.Write(msg); err != nil {
L.Error().Err(err).Str("Container", containerName).Msg("failed to write log message to file")
break
}
}
}
return nil
}
10 changes: 4 additions & 6 deletions wasp/examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA=
github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
Expand Down Expand Up @@ -188,8 +188,7 @@ github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
Expand Down Expand Up @@ -814,8 +813,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
Expand Down
Loading