Basic Slack Hook
Send error and fatal logs to Slack:package main
import (
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
"github.com/drossan/go_logs/adapters"
)
func main() {
// Create Slack notifier
slackNotifier, err := adapters.NewSlackNotifier()
if err != nil {
panic(err)
}
// Create Slack hook (only send Error and Fatal levels)
slackHook := hooks.NewSlackHook(slackNotifier, go_logs.ErrorLevel)
// Create logger with Slack hook
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHook(slackHook),
)
// These won't go to Slack (below ErrorLevel)
logger.Info("Application started") // Not sent to Slack
logger.Warn("High memory usage") // Not sent to Slack
// These will be sent to Slack
logger.Error("Database connection failed",
go_logs.String("host", "db.example.com"),
go_logs.Int("port", 5432),
)
logger.Fatal("Critical system failure",
go_logs.String("component", "payment-processor"),
)
}
Configuration via Environment Variables
Configure Slack integration using environment variables:# Set Slack credentials
export SLACK_TOKEN="xoxb-your-bot-token"
export SLACK_CHANNEL_ID="C123456789"
package main
import (
"os"
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
"github.com/drossan/go_logs/adapters"
)
func main() {
// Slack notifier reads from environment variables
// SLACK_TOKEN and SLACK_CHANNEL_ID
slackNotifier, err := adapters.NewSlackNotifier()
if err != nil {
// Handle gracefully - app continues without Slack
logger, _ := go_logs.New()
logger.Warn("Slack notifications disabled", go_logs.Err(err))
return
}
slackHook := hooks.NewSlackHook(slackNotifier, go_logs.ErrorLevel)
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHook(slackHook),
)
logger.Error("Payment processing failed",
go_logs.String("transaction_id", "tx-12345"),
go_logs.Float64("amount", 99.99),
)
}
[ERROR] Payment processing failed transaction_id=tx-12345 amount=99.99
Dynamic Slack Level Control
Change which levels get sent to Slack at runtime:package main
import (
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
"github.com/drossan/go_logs/adapters"
)
func main() {
slackNotifier, _ := adapters.NewSlackNotifier()
slackHook := hooks.NewSlackHook(slackNotifier, go_logs.ErrorLevel)
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHook(slackHook),
)
// Initially only errors are sent to Slack
logger.Warn("Warning message") // Not sent
logger.Error("Error message") // Sent to Slack
// During incident - send warnings too
slackHook.SetLevel(go_logs.WarnLevel)
logger.Warn("Another warning") // Now sent to Slack
// After incident - back to errors only
slackHook.SetLevel(go_logs.ErrorLevel)
}
Production Setup with Error Grouping
Group similar errors to avoid Slack spam:package main
import (
"sync"
"time"
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
)
// RateLimitedSlackHook wraps SlackHook with rate limiting
type RateLimitedSlackHook struct {
hook *hooks.SlackHook
mu sync.Mutex
lastSent map[string]time.Time
interval time.Duration
}
func NewRateLimitedSlackHook(hook *hooks.SlackHook, interval time.Duration) *RateLimitedSlackHook {
return &RateLimitedSlackHook{
hook: hook,
lastSent: make(map[string]time.Time),
interval: interval,
}
}
func (h *RateLimitedSlackHook) Run(entry *go_logs.Entry) error {
h.mu.Lock()
defer h.mu.Unlock()
// Use message as deduplication key
key := entry.Message
// Check if we sent this message recently
if lastTime, exists := h.lastSent[key]; exists {
if time.Since(lastTime) < h.interval {
// Skip - sent too recently
return nil
}
}
// Send to Slack
if err := h.hook.Run(entry); err != nil {
return err
}
// Update last sent time
h.lastSent[key] = time.Now()
return nil
}
func main() {
slackNotifier, _ := adapters.NewSlackNotifier()
baseHook := hooks.NewSlackHook(slackNotifier, go_logs.ErrorLevel)
// Only send same error once per 5 minutes
slackHook := NewRateLimitedSlackHook(baseHook, 5*time.Minute)
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHook(slackHook),
)
// First error is sent
logger.Error("Database connection failed")
// Subsequent errors within 5 minutes are suppressed
logger.Error("Database connection failed") // Not sent
logger.Error("Database connection failed") // Not sent
// After 5 minutes, will be sent again
}
Multi-Channel Slack Notifications
Send different severity levels to different channels:package main
import (
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
"github.com/drossan/go_logs/adapters"
)
func main() {
// Create notifiers for different channels
errorsNotifier, _ := adapters.NewSlackNotifierWithChannel(
"xoxb-token",
"C123456789", // #errors channel
)
criticalNotifier, _ := adapters.NewSlackNotifierWithChannel(
"xoxb-token",
"C987654321", // #critical channel
)
// Errors go to #errors channel
errorsHook := hooks.NewSlackHook(errorsNotifier, go_logs.ErrorLevel)
// Fatal logs go to #critical channel
criticalHook := hooks.NewSlackHook(criticalNotifier, go_logs.FatalLevel)
// Register both hooks
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHooks(errorsHook, criticalHook),
)
logger.Error("API timeout") // Goes to #errors
logger.Fatal("Payment system down") // Goes to both #errors and #critical
}
Slack Notifications with Rich Context
Include detailed context in Slack messages:package main
import (
"os"
"runtime"
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
"github.com/drossan/go_logs/adapters"
)
func main() {
slackNotifier, _ := adapters.NewSlackNotifier()
slackHook := hooks.NewSlackHook(slackNotifier, go_logs.ErrorLevel)
// Create logger with service context
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHook(slackHook),
)
// Add service-level fields
serviceLogger := logger.With(
go_logs.String("service", "payment-api"),
go_logs.String("version", "1.2.3"),
go_logs.String("environment", "production"),
go_logs.String("hostname", getHostname()),
)
// Error with rich context
serviceLogger.Error("Payment processing failed",
go_logs.String("user_id", "user-123"),
go_logs.String("transaction_id", "tx-456"),
go_logs.Float64("amount", 99.99),
go_logs.String("payment_method", "credit_card"),
go_logs.Int("retry_count", 3),
)
}
func getHostname() string {
hostname, _ := os.Hostname()
return hostname
}
[ERROR] Payment processing failed service=payment-api version=1.2.3 environment=production hostname=prod-server-1 user_id=user-123 transaction_id=tx-456 amount=99.99 payment_method=credit_card retry_count=3
Testing Slack Integration
Test Slack hooks without spamming production channels:package main
import (
"testing"
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
)
// MockSlackNotifier for testing
type MockSlackNotifier struct {
Messages []string
}
func (m *MockSlackNotifier) SendNotification(message string) error {
m.Messages = append(m.Messages, message)
return nil
}
func TestSlackHook(t *testing.T) {
mock := &MockSlackNotifier{}
hook := hooks.NewSlackHook(mock, go_logs.ErrorLevel)
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithHook(hook),
)
// Log an error
logger.Error("Test error",
go_logs.String("key", "value"),
)
// Verify message was sent
if len(mock.Messages) != 1 {
t.Errorf("Expected 1 message, got %d", len(mock.Messages))
}
if !strings.Contains(mock.Messages[0], "Test error") {
t.Errorf("Message doesn't contain expected text: %s", mock.Messages[0])
}
}
Graceful Degradation
Handle Slack failures without affecting application:package main
import (
"github.com/drossan/go_logs"
"github.com/drossan/go_logs/hooks"
"github.com/drossan/go_logs/adapters"
)
func main() {
// Try to create Slack notifier
slackNotifier, err := adapters.NewSlackNotifier()
var opts []go_logs.Option
opts = append(opts, go_logs.WithLevel(go_logs.InfoLevel))
if err == nil {
// Slack is configured - add hook
slackHook := hooks.NewSlackHook(slackNotifier, go_logs.ErrorLevel)
opts = append(opts, go_logs.WithHook(slackHook))
}
logger, _ := go_logs.New(opts...)
if err != nil {
logger.Warn("Slack notifications disabled - missing credentials")
} else {
logger.Info("Slack notifications enabled")
}
// Application continues normally
logger.Error("An error occurred") // Sent to Slack if available
}
Next Steps
Hooks System
Learn more about the hooks system
Production Setup
Complete production configuration