Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
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
13 changes: 6 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

# Project configuration
BINARY_NAME := gonzo
CMD_DIR := ./cmd/gonzo
BUILD_DIR := ./build
DIST_DIR := ./dist

Expand Down Expand Up @@ -58,7 +57,7 @@ build: deps ## Build the TUI binary
@echo "$(BLUE)Building TUI version...$(NC)"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) \
$(GO) build $(BUILD_FLAGS) -o $(BUILD_DIR)/$(BINARY_NAME) $(CMD_DIR)
$(GO) build $(BUILD_FLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)
@echo "$(GREEN)✓ Built $(BUILD_DIR)/$(BINARY_NAME)$(NC)"

# Cross-platform builds
Expand All @@ -70,25 +69,25 @@ cross-build: clean deps ## Build for multiple platforms
@echo "$(YELLOW)Building for linux/amd64...$(NC)"
@mkdir -p $(DIST_DIR)/linux-amd64
@CGO_ENABLED=$(CGO_ENABLED) GOOS=linux GOARCH=amd64 \
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/linux-amd64/$(BINARY_NAME) $(CMD_DIR)
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/linux-amd64/$(BINARY_NAME)

# macOS amd64
@echo "$(YELLOW)Building for darwin/amd64...$(NC)"
@mkdir -p $(DIST_DIR)/darwin-amd64
@CGO_ENABLED=$(CGO_ENABLED) GOOS=darwin GOARCH=amd64 \
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/darwin-amd64/$(BINARY_NAME) $(CMD_DIR)
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/darwin-amd64/$(BINARY_NAME)

# macOS arm64
@echo "$(YELLOW)Building for darwin/arm64...$(NC)"
@mkdir -p $(DIST_DIR)/darwin-arm64
@CGO_ENABLED=$(CGO_ENABLED) GOOS=darwin GOARCH=arm64 \
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/darwin-arm64/$(BINARY_NAME) $(CMD_DIR)
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/darwin-arm64/$(BINARY_NAME)

# Windows amd64
@echo "$(YELLOW)Building for windows/amd64...$(NC)"
@mkdir -p $(DIST_DIR)/windows-amd64
@CGO_ENABLED=$(CGO_ENABLED) GOOS=windows GOARCH=amd64 \
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/windows-amd64/$(BINARY_NAME).exe $(CMD_DIR)
$(GO) build $(BUILD_FLAGS) -o $(DIST_DIR)/windows-amd64/$(BINARY_NAME).exe

@echo "$(GREEN)✓ Cross-platform builds complete in $(DIST_DIR)/$(NC)"

Expand Down Expand Up @@ -157,7 +156,7 @@ lint: ## Run linter (requires golangci-lint)
# Installation
install: build ## Install binary to $GOPATH/bin
@echo "$(BLUE)Installing binary...$(NC)"
@$(GO) install $(BUILD_FLAGS) $(CMD_DIR)
@$(GO) install $(BUILD_FLAGS)
@echo "$(GREEN)✓ Installed $(BINARY_NAME) to $(shell go env GOPATH)/bin$(NC)"

uninstall: ## Remove installed binary
Expand Down
6 changes: 6 additions & 0 deletions art.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
_____ _
| __ \ | |
| | \/ ___ _ __ _______ | |
| | __ / _ \| '_ \|_ / _ \| |
| |_\ \ (_) | | | |/ / (_) |_|
\____/\___/|_| |_/___\___/(_)
29 changes: 13 additions & 16 deletions cmd/gonzo/app.go → cmd/app.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"bufio"
Expand All @@ -21,21 +21,15 @@ import (

tea "github.com/charmbracelet/bubbletea"
"github.com/spf13/cobra"
goversion "github.com/caarlos0/go-version"
)

// runApp initializes and runs the application
func runApp(cmd *cobra.Command, args []string) error {
// Check if version flag was used
if v, _ := cmd.Flags().GetBool("version"); v {
versionCmd.Run(cmd, args)
return nil
}

func runApp(cmd *cobra.Command, args []string, versionInfo goversion.Info, cfg Config) error {
// Start version checking in background (if not disabled)
var versionChecker *versioncheck.Checker
if !cfg.DisableVersionCheck {
currentVersion, currentCommit := GetVersionInfo()
versionChecker = versioncheck.NewChecker(currentVersion, currentCommit)
versionChecker = versioncheck.NewChecker(versionInfo.GitVersion, versionInfo.GitCommit)
versionChecker.CheckInBackground()
}

Expand Down Expand Up @@ -96,6 +90,7 @@ func runApp(cmd *cobra.Command, args []string) error {
}

tuiModel := &simpleTuiModel{
cfg: cfg,
formatDetector: formatDetector,
logConverter: logConverter,
customParser: customParser,
Expand Down Expand Up @@ -157,6 +152,7 @@ type simpleTuiModel struct {
updateInterval time.Duration
testMode bool
ctx context.Context
cfg Config
cancelFunc context.CancelFunc
versionChecker *versioncheck.Checker

Expand Down Expand Up @@ -196,15 +192,16 @@ func (m *simpleTuiModel) Init() tea.Cmd {
m.lastFreqReset = time.Now()

// Check if Victoria Logs receiver is enabled
if cfg.VmlogsURL != "" {
if m.cfg.VmlogsURL != "" {
// Victoria Logs input mode
m.hasVmlogsInput = true
m.inputChan = make(chan string, 100)

// Create and start Victoria Logs receiver
params := make(map[string]string)
// Add any default parameters here if needed
m.vmlogsReceiver = vmlogs.NewReceiver(cfg.VmlogsURL, cfg.VmlogsUser, cfg.VmlogsPassword, cfg.VmlogsQuery, params)
m.vmlogsReceiver = vmlogs.NewReceiver(m.cfg.VmlogsURL, m.cfg.VmlogsUser,
m.cfg.VmlogsPassword, m.cfg.VmlogsQuery, params)
if err := m.vmlogsReceiver.Start(); err != nil {
log.Printf("Error starting Victoria Logs receiver: %v", err)
// Fall back to other input methods if Victoria Logs fails
Expand All @@ -216,13 +213,13 @@ func (m *simpleTuiModel) Init() tea.Cmd {
}

// Check if OTLP receiver is enabled (only if Victoria Logs is not enabled)
if !m.hasVmlogsInput && cfg.OTLPEnabled {
if !m.hasVmlogsInput && m.cfg.OTLPEnabled {
// OTLP input mode
m.hasOTLPInput = true
m.inputChan = make(chan string, 100)

// Create and start OTLP receiver
m.otlpReceiver = otlpreceiver.NewReceiver(cfg.OTLPGRPCPort, cfg.OTLPHTTPPort)
m.otlpReceiver = otlpreceiver.NewReceiver(m.cfg.OTLPGRPCPort, m.cfg.OTLPHTTPPort)
if err := m.otlpReceiver.Start(); err != nil {
log.Printf("Error starting OTLP receiver: %v", err)
// Fall back to other input methods if OTLP fails
Expand All @@ -234,14 +231,14 @@ func (m *simpleTuiModel) Init() tea.Cmd {
}

// Check if we have file inputs specified (only if Victoria Logs and OTLP are not enabled)
if !m.hasVmlogsInput && !m.hasOTLPInput && len(cfg.Files) > 0 {
if !m.hasVmlogsInput && !m.hasOTLPInput && len(m.cfg.Files) > 0 {
// File input mode
m.hasFileInput = true
m.inputChan = make(chan string, 100)

// Create file reader
var err error
m.fileReader, err = filereader.New(cfg.Files, cfg.Follow)
m.fileReader, err = filereader.New(m.cfg.Files, m.cfg.Follow)
if err != nil {
log.Printf("Error setting up file reader: %v", err)
// Fall back to stdin if file reading fails
Expand Down
72 changes: 72 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package cmd

import (
"time"
"os"
"log"
"strings"
"github.com/spf13/viper"
)

// Config struct for application configuration
type Config struct {
MemorySize int `mapstructure:"memory-size"`
UpdateInterval time.Duration `mapstructure:"update-interval"`
LogBuffer int `mapstructure:"log-buffer"`
TestMode bool `mapstructure:"test-mode"`
ConfigFile string `mapstructure:"config"`
AIModel string `mapstructure:"ai-model"`
Files []string `mapstructure:"files"`
Follow bool `mapstructure:"follow"`
OTLPEnabled bool `mapstructure:"otlp-enabled"`
OTLPGRPCPort int `mapstructure:"otlp-grpc-port"`
OTLPHTTPPort int `mapstructure:"otlp-http-port"`
VmlogsURL string `mapstructure:"vmlogs-url"`
VmlogsUser string `mapstructure:"vmlogs-user"`
VmlogsPassword string `mapstructure:"vmlogs-password"`
VmlogsQuery string `mapstructure:"vmlogs-query"`
Skin string `mapstructure:"skin"`
StopWords []string `mapstructure:"stop-words"`
Format string `mapstructure:"format"`
DisableVersionCheck bool `mapstructure:"disable-version-check"`
ReverseScrollWheel bool `mapstructure:"reverse-scroll-wheel"`
}


func initConfig(cfgFile string) Config {
if cfgFile != "" {
// Use config file from the flag
viper.SetConfigFile(cfgFile)
} else {
// Find XDG config directory
home, err := os.UserHomeDir()
if err != nil {
log.Printf("Error finding home directory: %v", err)
} else {
configDir := home + "/.config/gonzo"
viper.AddConfigPath(configDir)
viper.SetConfigType("yaml")
viper.SetConfigName("config")
}
}

// Support environment variables
viper.SetEnvPrefix("GONZO")
viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))

// Read config file if it exists
if err := viper.ReadInConfig(); err == nil {
log.Printf("Using config file: %s", viper.ConfigFileUsed())
}

var cfg Config

// Unmarshal config
if err := viper.Unmarshal(&cfg); err != nil {
log.Fatalf("Unable to decode config: %v", err)
}

return cfg
}

57 changes: 57 additions & 0 deletions cmd/examples.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Analyze logs from stdin
cat application.log | gonzo

# Read logs directly from files
gonzo -f application.log -f error.log

# Follow log files in real-time (like tail -f)
gonzo -f /var/log/app.log --follow

# Use glob patterns to read multiple files
gonzo -f "/var/log/*.log" --follow

# Stream logs from kubectl
kubectl logs -f deployment/my-app | gonzo

# With custom settings
gonzo -f logs.json --update-interval=2s --log-buffer=2000

# With AI analysis (auto-selects best model)
export OPENAI_API_KEY=sk-your-key-here
gonzo -f application.log --ai-model="gpt-4"

# With local AI server (auto-selects available model)
export OPENAI_API_BASE="http://127.0.0.1:1234/v1"
export OPENAI_API_KEY="local-key"
gonzo -f logs.json --follow

# With OTLP listener (both gRPC and HTTP)
gonzo --otlp-enabled

# With custom ports
gonzo --otlp-enabled --otlp-grpc-port=4317 --otlp-http-port=4318

# Stream logs from Victoria Logs
gonzo --vmlogs-url="http://localhost:9428" --vmlogs-query="*"

# With authentication and custom query
gonzo --vmlogs-url="https://vmlogs.example.com" --vmlogs-user="myuser" --vmlogs-password="mypass" --vmlogs-query='level:error'

# Using environment variables for authentication
export GONZO_VMLOGS_USER="myuser"
export GONZO_VMLOGS_PASSWORD="mypass"
gonzo --vmlogs-url="https://vmlogs.example.com" --vmlogs-query='service:"myapp"'

# Using a custom color scheme/skin
gonzo --skin=dracula

# Or via environment variable
export GONZO_SKIN=monokai
gonzo -f application.log

# Using a custom log format
gonzo --format=nodejs -f app.log

# Use built-in formats explicitly
gonzo --format=json -f structured.log
gonzo --format=text -f plain.log
2 changes: 1 addition & 1 deletion cmd/gonzo/extractors.go → cmd/extractors.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
Loading