Development Setup

Get your development environment ready to contribute to Gonzo. This guide covers everything from prerequisites to running your first build.

Prerequisites

Required Software

Go Programming Language:

  • Version: 1.21 or higher

  • Download: https://golang.org/dl/

  • Installation guide: https://golang.org/doc/install

# Verify Go installation
go version
# Should show: go version go1.21.x or higher

Git:

  • Version: 2.0 or higher

  • Download: https://git-scm.com/downloads

# Verify Git installation
git --version

Make (optional but recommended):

  • Usually pre-installed on macOS/Linux

  • Windows: Install via Chocolatey or use Git Bash

# Verify Make installation
make --version

Code Editor:

  • VS Code with Go extension

  • GoLand

  • Vim/Neovim with vim-go

  • Any editor with Go support

Terminal:

  • Modern terminal with good Unicode support

  • Recommendations: iTerm2, Alacritty, Windows Terminal

Additional Tools:

# Code formatting
go install golang.org/x/tools/cmd/goimports@latest

# Linting
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

# Testing
go install gotest.tools/gotestsum@latest

Getting the Source Code

Fork the Repository

  1. Go to https://github.com/control-theory/gonzo

  2. Click "Fork" button (top right)

  3. This creates your own copy of the repository

Clone Your Fork

# Clone your fork
git clone https://github.com/YOUR-USERNAME/gonzo.git
cd gonzo

# Add upstream remote
git remote add upstream https://github.com/control-theory/gonzo.git

# Verify remotes
git remote -v
# Should show:
# origin    https://github.com/YOUR-USERNAME/gonzo.git (fetch)
# origin    https://github.com/YOUR-USERNAME/gonzo.git (push)
# upstream  https://github.com/control-theory/gonzo.git (fetch)
# upstream  https://github.com/control-theory/gonzo.git (push)

Sync with Upstream

Keep your fork up to date:

# Fetch latest changes from upstream
git fetch upstream

# Switch to main branch
git checkout main

# Merge upstream changes
git merge upstream/main

# Push to your fork
git push origin main

Project Structure

Understanding the codebase:

gonzo/
├── cmd/
│   └── gonzo/              # Application entry point
│       ├── main.go         # Main function
│       ├── app.go          # Application setup
│       ├── extractors.go   # Data extraction
│       └── processing.go   # Log processing

├── internal/               # Private application code
│   ├── tui/               # Terminal UI (Bubble Tea)
│   │   ├── model.go       # Application model
│   │   ├── update.go      # Update logic
│   │   ├── view.go        # View rendering
│   │   ├── components.go  # UI components
│   │   ├── charts.go      # Chart rendering
│   │   ├── tables.go      # Table components
│   │   ├── modals.go      # Modal dialogs
│   │   ├── navigation.go  # Navigation handling
│   │   ├── formatting.go  # Text formatting
│   │   ├── severity.go    # Severity handling
│   │   ├── styles.go      # UI styles
│   │   └── drain3_manager.go # Drain3 integration
│   │
│   ├── analyzer/          # Log analysis
│   │   ├── otlp.go       # OTLP analysis
│   │   └── text.go       # Text analysis
│   │
│   ├── memory/            # Data storage
│   │   └── frequency.go   # Frequency tracking
│   │
│   ├── otlplog/          # OTLP handling
│   │   ├── converter.go   # Log conversion
│   │   └── detector.go    # Format detection
│   │
│   ├── drain3/           # Log clustering
│   │   └── impl.go       # Drain3 implementation
│   │
│   ├── ai/               # AI integration
│   │   └── openai.go     # OpenAI API
│   │
│   ├── output/           # Output handlers
│   │   └── stdout.go     # Standard output
│   │
│   └── reader/           # Input readers
│       └── stdin.go      # Standard input

├── examples/             # Example files
│   ├── config.yml       # Sample config
│   └── formats/         # Custom formats

├── docs/                # Documentation
├── Makefile            # Build automation
├── go.mod              # Go module
└── go.sum              # Dependencies

Building Gonzo

Quick Build

# Build using Make (recommended)
make build

# Binary created at: ./bin/gonzo
./bin/gonzo --version

Manual Build

# Build without Make
go build -o bin/gonzo ./cmd/gonzo

# Run
./bin/gonzo --version

Development Build

# Build with all checks
make dev

# This runs:
# - go fmt (format code)
# - go vet (check for issues)
# - go test (run tests)
# - go build (compile binary)

Build for All Platforms

# Cross-compile for multiple platforms
make cross-build

# Creates binaries for:
# - Linux (amd64, arm64)
# - macOS (amd64, arm64)
# - Windows (amd64)

Running Tests

Unit Tests

# Run all tests
make test

# Or with go directly
go test ./...

# Verbose output
go test -v ./...

# Specific package
go test ./internal/analyzer/...

Race Detection

# Detect race conditions
make test-race

# Or with go directly
go test -race ./...

Coverage Report

# Generate coverage report
go test -coverprofile=coverage.out ./...

# View coverage in browser
go tool cover -html=coverage.out

Integration Tests

# Run integration tests
make test-integration

# Or with tags
go test -tags=integration ./...

Running Gonzo in Development

Basic Run

# Build and run
make build
./bin/gonzo -f examples/sample.log

# Or run directly without building
go run ./cmd/gonzo -f examples/sample.log

With Sample Data

# Run demo with sample logs
make demo

# This generates sample logs and runs Gonzo

Testing Features

Test file input:

# Create test log file
cat > test.log << 'EOF'
{"level":"info","msg":"Test 1"}
{"level":"error","msg":"Test 2"}
{"level":"warn","msg":"Test 3"}
EOF

# Run Gonzo
./bin/gonzo -f test.log

Test stdin:

# Pipe logs to Gonzo
echo '{"level":"info","msg":"Hello"}' | ./bin/gonzo

Test follow mode:

# In terminal 1
./bin/gonzo -f /tmp/live.log --follow

# In terminal 2
while true; do 
  echo "{\"level\":\"info\",\"msg\":\"Log $(date)\"}" >> /tmp/live.log
  sleep 1
done

Test OTLP receiver:

# Start with OTLP enabled
./bin/gonzo --otlp-enabled

# In another terminal, send test log
curl -X POST http://localhost:4318/v1/logs \
  -H "Content-Type: application/json" \
  -d '{"resourceLogs":[{"scopeLogs":[{"logRecords":[{"body":{"stringValue":"test"}}]}]}]}'

Development Workflow

1. Create a Feature Branch

# Sync with upstream first
git fetch upstream
git checkout main
git merge upstream/main

# Create feature branch
git checkout -b feature/my-awesome-feature

2. Make Changes

# Edit files
vim internal/tui/model.go

# Format code
go fmt ./...

# Or use goimports
goimports -w .

3. Test Changes

# Run tests
make test

# Build and test manually
make build
./bin/gonzo -f test.log

4. Commit Changes

# Stage changes
git add .

# Commit with meaningful message
git commit -m "feat: add awesome feature

Detailed description of what this feature does and why.

Closes #123"

5. Push to Your Fork

# Push feature branch to your fork
git push origin feature/my-awesome-feature

6. Create Pull Request

  1. Go to your fork on GitHub

  2. Click "Compare & pull request"

  3. Fill out PR template

  4. Submit pull request

Code Style

Formatting

# Format all Go code
go fmt ./...

# Or use goimports (better)
goimports -w .

Linting

# Run golangci-lint
golangci-lint run

# Fix auto-fixable issues
golangci-lint run --fix

Code Conventions

Naming:

  • Use camelCase for variables and functions

  • Use PascalCase for exported names

  • Keep names short but descriptive

  • Avoid abbreviations unless common

Comments:

// Good: Concise description
// ParseLog parses a log line and returns structured data.
func ParseLog(line string) (*Log, error) {
    // Implementation
}

// Bad: Redundant or missing
func ParseLog(line string) (*Log, error) {
    // Implementation
}

Error Handling:

// Good: Wrap errors with context
if err != nil {
    return fmt.Errorf("failed to parse log: %w", err)
}

// Bad: Lose error context
if err != nil {
    return err
}

Debugging

Using Delve

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

# Debug Gonzo
dlv debug ./cmd/gonzo -- -f test.log

# In Delve:
# (dlv) break main.main
# (dlv) continue
# (dlv) next
# (dlv) print variableName

Logging Debug Info

# Run with verbose flag
./bin/gonzo -v -f test.log 2> debug.log

# Check debug output
tail -f debug.log

VS Code Debug Configuration

Create .vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Gonzo",
      "type": "go",
      "request": "launch",
      "mode": "debug",
      "program": "${workspaceFolder}/cmd/gonzo",
      "args": ["-f", "test.log"],
      "env": {},
      "showLog": true
    },
    {
      "name": "Debug Gonzo with OTLP",
      "type": "go",
      "request": "launch",
      "mode": "debug",
      "program": "${workspaceFolder}/cmd/gonzo",
      "args": ["--otlp-enabled"],
      "env": {},
      "showLog": true
    }
  ]
}

Common Development Tasks

Adding a New Feature

  1. Plan the feature

    • Open an issue to discuss

    • Get feedback from maintainers

    • Design the implementation

  2. Implement the feature

    • Create feature branch

    • Write code following style guide

    • Add tests for new functionality

    • Update documentation

  3. Test thoroughly

    • Unit tests

    • Integration tests

    • Manual testing

  4. Submit for review

    • Create pull request

    • Address review comments

    • Wait for approval

Fixing a Bug

  1. Reproduce the bug

    • Create minimal test case

    • Document steps to reproduce

  2. Write a failing test

    • Test should fail before fix

    • Test should pass after fix

  3. Fix the bug

    • Make minimal changes

    • Ensure test passes

  4. Submit fix

    • Reference issue in commit

    • Include test in PR

Updating Dependencies

# Update all dependencies
go get -u ./...

# Tidy dependencies
go mod tidy

# Verify everything works
make test

Performance Profiling

CPU Profiling

# Build with profiling
go build -o bin/gonzo ./cmd/gonzo

# Run with CPU profiling
./bin/gonzo -f large.log -cpuprofile=cpu.prof

# Analyze profile
go tool pprof cpu.prof
# Commands: top, list, web

Memory Profiling

# Run with memory profiling
./bin/gonzo -f large.log -memprofile=mem.prof

# Analyze profile
go tool pprof mem.prof

Benchmarking

# Run benchmarks
go test -bench=. ./...

# With memory stats
go test -bench=. -benchmem ./...

# Specific benchmark
go test -bench=BenchmarkParsing ./internal/analyzer/

Troubleshooting Development Issues

Build Fails

Dependency issues:

# Clean module cache
go clean -modcache

# Re-download dependencies
go mod download

# Rebuild
make build

Version mismatch:

# Check Go version
go version

# Should be 1.21 or higher
# Update if needed

Tests Fail

Race conditions:

# Run with race detector
go test -race ./...

# Fix any race conditions found

Flaky tests:

  • Run tests multiple times

  • Check for timing dependencies

  • Use proper synchronization

IDE Issues

VS Code Go extension problems:

# Reinstall Go tools
# Command Palette: Go: Install/Update Tools

Gopls issues:

# Clean gopls cache
rm -rf ~/Library/Caches/gopls  # macOS
rm -rf ~/.cache/gopls          # Linux

Getting Help

Resources

  • GitHub Issues: Ask questions, report bugs

  • GitHub Discussions: General discussions

  • Code Review: Learn from PR feedback

  • Documentation: Read existing docs thoroughly

Communication

  • Be respectful: Follow Code of Conduct

  • Be patient: Maintainers are volunteers

  • Be clear: Provide context and details

  • Be helpful: Help others when you can

Next Steps

Now that your development environment is set up:

  1. Read the codebase: Familiarize yourself with the structure

  2. Pick an issue: Look for "good first issue" labels

  3. Make a change: Start with something small

  4. Submit a PR: Get feedback and iterate

Related Documentation:

  • Contribution Guidelines - Detailed contribution process

  • Community - How to engage with the community

  • Architecture Overview - Understanding the codebase

Last updated