Merge pull request #922 from brngates98/add-ai-context-files

Add AI context files for major LLMs
This commit is contained in:
Cody Lee
2026-01-27 20:51:34 -06:00
committed by GitHub
4 changed files with 786 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
# UnPoller - Cursor AI Rules
## Project Overview
UnPoller is a Go application that collects metrics from UniFi network controllers and exports them to various backends (InfluxDB, Prometheus, Loki, DataDog). The architecture is plugin-based with input and output plugins.
## Architecture
### Core Components
- **main.go**: Entry point, loads plugins via blank imports
- **pkg/poller/**: Core library providing input/output interfaces and plugin management
- **pkg/inputunifi/**: Input plugin for UniFi controller data collection
- **pkg/influxunifi/**: Output plugin for InfluxDB
- **pkg/promunifi/**: Output plugin for Prometheus
- **pkg/lokiunifi/**: Output plugin for Loki
- **pkg/datadogunifi/**: Output plugin for DataDog
- **pkg/webserver/**: Web server for health checks and metrics
- **pkg/mysqlunifi/**: MySQL output plugin
### Plugin System
- Plugins are loaded via blank imports (`_ "github.com/unpoller/unpoller/pkg/inputunifi"`)
- Input plugins implement the `Input` interface from `pkg/poller/inputs.go`
- Output plugins implement the `Output` interface from `pkg/poller/outputs.go`
- The poller core automatically discovers and initializes imported plugins
- Configuration is automatically unmarshaled from config files (TOML/JSON/YAML) and environment variables
## Code Style & Conventions
### Go Standards
- Use Go 1.25.5+ features
- Follow standard Go formatting (gofmt)
- Use `golangci-lint` with the project's `.golangci.yaml` configuration
- Enable linters: `nlreturn`, `revive`, `tagalign`, `testpackage`, `wsl_v5`
- Use `//nolint:gci` for import ordering when needed
### Naming Conventions
- Package names should be lowercase, single word
- Exported types/functions use PascalCase
- Unexported types/functions use camelCase
- Constants use PascalCase with descriptive names
- Error variables should be named `err` and checked immediately
### Error Handling
- Always check errors, don't ignore them
- Use `github.com/pkg/errors` for error wrapping when appropriate
- Return errors from functions, don't log and continue
- Use descriptive error messages
### Configuration
- Configuration uses `golift.io/cnfg` and `golift.io/cnfgfile`
- Environment variables use `UP_` prefix (defined in `ENVConfigPrefix`)
- Support TOML (default), JSON, and YAML formats
- Config structs should have tags: `json`, `toml`, `xml`, `yaml`
### Testing
- Use `testpackage` linter - tests should be in separate `_test` packages
- Use `github.com/stretchr/testify` for assertions
- Integration tests use `integration_test_expectations.yaml` files
### Logging
- Use structured logging via logger interfaces
- Log levels: ERROR, WARN, INFO, DEBUG
- Prefix log messages with `[LEVEL]` when using standard log package
## Dependencies
### Key Libraries
- `github.com/unpoller/unifi/v5` - UniFi API client (local replace: `/Users/briangates/unifi`)
- `golift.io/cnfg` - Configuration management
- `golift.io/cnfgfile` - Config file parsing
- `github.com/spf13/pflag` - CLI flag parsing
- `github.com/gorilla/mux` - HTTP router
- `github.com/prometheus/client_golang` - Prometheus metrics
### Output Backends
- InfluxDB: `github.com/influxdata/influxdb1-client` and `github.com/influxdata/influxdb-client-go/v2`
- Prometheus: `github.com/prometheus/client_golang`
- Loki: Custom HTTP client
- DataDog: `github.com/DataDog/datadog-go/v5`
## Project Structure
```
unpoller/
├── main.go # Entry point
├── pkg/
│ ├── poller/ # Core plugin system
│ ├── inputunifi/ # UniFi input plugin
│ ├── influxunifi/ # InfluxDB output
│ ├── promunifi/ # Prometheus output
│ ├── lokiunifi/ # Loki output
│ ├── datadogunifi/ # DataDog output
│ ├── mysqlunifi/ # MySQL output
│ └── webserver/ # Web server
├── examples/ # Configuration examples
├── init/ # Init scripts (systemd, docker, etc.)
└── scripts/ # Build/deployment scripts
```
## Common Patterns
### Adding a New Output Plugin
1. Create new package in `pkg/` (e.g., `pkg/myoutput/`)
2. Implement `Output` interface from `pkg/poller/outputs.go`
3. Register plugin in `init()` function
4. Add blank import to `main.go`
5. Add configuration struct with proper tags
6. Create README.md in package directory
### Adding a New Input Plugin
1. Create new package in `pkg/` (e.g., `pkg/myinput/`)
2. Implement `Input` interface from `pkg/poller/inputs.go`
3. Register plugin in `init()` function
4. Add blank import to `main.go`
5. Add configuration struct with proper tags
### Device Type Reporting
- Device types: UAP, USG, USW, UDM, UBB, UCI, UXG, PDU
- Each output plugin has device-specific reporting functions (e.g., `uap.go`, `usg.go`)
- Follow existing patterns in `pkg/promunifi/` or `pkg/influxunifi/`
## Important Notes
- The `pkg/poller` library is generic and has no knowledge of UniFi, Influx, Prometheus, etc.
- It provides interfaces for any type of input/output plugin
- Use `[]any` types for flexibility in the core library
- Configuration is automatically loaded from files and environment variables
- The application supports multiple UniFi controllers via configuration
- Timezone can be set via `TZ` environment variable
## Build & Deployment
- Uses GitHub Actions for CI/CD
- Uses `goreleaser` for multi-platform builds
- Supports: Linux, macOS, Windows, FreeBSD
- Docker images built automatically
- Homebrew formula for macOS
- Configuration examples in `examples/` directory
## When Writing Code
- Keep functions focused and single-purpose
- Use interfaces for testability
- Follow the existing plugin patterns
- Document exported functions and types
- Add appropriate error handling
- Consider cross-platform compatibility (Windows, macOS, Linux, BSD)
- Use context.Context for cancellable operations
- Respect timeouts and deadlines
+127
View File
@@ -0,0 +1,127 @@
# UnPoller - GitHub Copilot Instructions
## Project Overview
UnPoller is a Go application that collects metrics and events from UniFi network controllers and exports them to monitoring backends (InfluxDB, Prometheus, Loki, DataDog, MySQL). The application uses a plugin-based architecture with a generic core.
## Architecture
### Plugin System
- **Core Library** (`pkg/poller/`): Generic plugin system with input/output interfaces
- **Input Plugins**: Collect data (e.g., `pkg/inputunifi/`)
- **Output Plugins**: Export data to backends (e.g., `pkg/influxunifi/`, `pkg/promunifi/`)
- **Plugin Discovery**: Automatic via blank imports in `main.go`
### Key Interfaces
**Input Interface**:
```go
type Input interface {
GetMetrics() (*Metrics, error)
GetEvents() (*Events, error)
}
```
**Output Interface**:
```go
type Output interface {
WriteMetrics(*Metrics) error
WriteEvents(*Events) error
}
```
## Code Style
### Go Conventions
- Go 1.25.5+
- Use `gofmt` formatting
- Follow `.golangci.yaml` linting rules
- Enabled linters: `nlreturn`, `revive`, `tagalign`, `testpackage`, `wsl_v5`
### Naming
- Packages: `lowercase`
- Exported: `PascalCase`
- Unexported: `camelCase`
- Errors: Always `err`, check immediately
### Error Handling
```go
if err != nil {
return fmt.Errorf("context: %w", err)
}
```
### Configuration
All config structs must include format tags:
```go
type Config struct {
Field string `json:"field" toml:"field" xml:"field" yaml:"field"`
}
```
Environment variables use `UP_` prefix.
## Common Patterns
### Plugin Registration
```go
func init() {
poller.RegisterInput(&Input{})
// or
poller.RegisterOutput(&Output{})
}
```
### Device Type Reporting
Each output plugin has device-specific functions:
- `UAP()` - Access Points
- `USG()` - Security Gateways
- `USW()` - Switches
- `UDM()` - Dream Machines
- `UXG()` - Next-Gen Gateways
- `UBB()` - Building Bridges
- `UCI()` - Industrial devices
- `PDU()` - Power Distribution Units
### Adding New Plugin
1. Create package in `pkg/`
2. Implement `Input` or `Output` interface
3. Register in `init()`
4. Add blank import to `main.go`
5. Add config struct with tags
6. Create `README.md`
## Dependencies
### Core
- `github.com/unpoller/unifi/v5` - UniFi API (local: `/Users/briangates/unifi`)
- `golift.io/cnfg` - Configuration
- `golift.io/cnfgfile` - Config parsing
- `github.com/spf13/pflag` - CLI flags
### Outputs
- InfluxDB: `github.com/influxdata/influxdb1-client`, `github.com/influxdata/influxdb-client-go/v2`
- Prometheus: `github.com/prometheus/client_golang`
- DataDog: `github.com/DataDog/datadog-go/v5`
- Loki: Custom HTTP client
## Important Notes
- `pkg/poller` core is generic - no UniFi/backend knowledge
- Support Windows, macOS, Linux, BSD
- Configuration: TOML (default), JSON, YAML, env vars
- Always check and return errors
- Use `context.Context` for cancellable operations
- Tests in `_test` packages
- Use `github.com/stretchr/testify` for assertions
## When Writing Code
1. Follow existing plugin patterns
2. Keep core library generic
3. Check all errors
4. Document exported functions
5. Write tests in `_test` packages
6. Consider cross-platform compatibility
7. Use structured logging
8. Respect timeouts and deadlines
+270
View File
@@ -0,0 +1,270 @@
# UnPoller - AI Agent Context
This file provides comprehensive context for AI coding assistants working on the UnPoller project.
## Project Identity
**Name**: UnPoller (UniFi Poller)
**Language**: Go 1.25.5+
**Purpose**: Collect metrics and events from UniFi network controllers and export to monitoring backends
**Repository**: https://github.com/unpoller/unpoller
**Documentation**: https://unpoller.com
## Architecture Overview
UnPoller uses a **plugin-based architecture** with a generic core that provides input/output interfaces. The core library (`pkg/poller`) has no knowledge of UniFi or specific backends - it's a generic plugin system.
### Core Components
1. **Plugin System** (`pkg/poller/`):
- Generic input/output interfaces
- Automatic plugin discovery via blank imports
- Configuration management (TOML/JSON/YAML + env vars)
- Metrics and events aggregation
2. **Input Plugins**:
- `pkg/inputunifi/` - Collects data from UniFi controllers
3. **Output Plugins**:
- `pkg/influxunifi/` - InfluxDB (v1 and v2)
- `pkg/promunifi/` - Prometheus
- `pkg/lokiunifi/` - Loki
- `pkg/datadogunifi/` - DataDog
- `pkg/mysqlunifi/` - MySQL
4. **Web Server** (`pkg/webserver/`):
- Health checks
- Metrics endpoint
- Plugin information
## Code Organization
### Directory Structure
```
unpoller/
├── main.go # Entry point, loads plugins
├── pkg/
│ ├── poller/ # Core plugin system (generic)
│ │ ├── config.go # Configuration structures
│ │ ├── inputs.go # Input plugin interface
│ │ ├── outputs.go # Output plugin interface
│ │ ├── start.go # Application startup
│ │ └── commands.go # CLI commands
│ ├── inputunifi/ # UniFi input plugin
│ ├── influxunifi/ # InfluxDB output
│ ├── promunifi/ # Prometheus output
│ ├── lokiunifi/ # Loki output
│ ├── datadogunifi/ # DataDog output
│ ├── mysqlunifi/ # MySQL output
│ └── webserver/ # Web server
├── examples/ # Configuration examples
├── init/ # Init scripts (systemd, docker, etc.)
└── scripts/ # Build scripts
```
### Plugin Interface Pattern
**Input Plugin**:
```go
type Input interface {
GetMetrics() (*Metrics, error)
GetEvents() (*Events, error)
}
```
**Output Plugin**:
```go
type Output interface {
WriteMetrics(*Metrics) error
WriteEvents(*Events) error
}
```
**Registration**:
```go
func init() {
poller.RegisterInput(&MyInput{})
// or
poller.RegisterOutput(&MyOutput{})
}
```
## Coding Standards
### Go Style
- **Formatting**: Standard `gofmt`
- **Linting**: `.golangci.yaml` configuration
- Enabled: `nlreturn`, `revive`, `tagalign`, `testpackage`, `wsl_v5`
- **Imports**: Use `//nolint:gci` when import ordering needs exception
### Naming Conventions
- Packages: `lowercase`, single word
- Exported: `PascalCase`
- Unexported: `camelCase`
- Constants: `PascalCase` with descriptive names
- Errors: Always `err`, checked immediately
### Error Handling
```go
// ✅ Good
if err != nil {
return fmt.Errorf("context: %w", err)
}
// ❌ Bad
_ = functionThatReturnsError()
```
### Configuration Pattern
All configuration structs must include:
```go
type Config struct {
Field string `json:"field" toml:"field" xml:"field" yaml:"field"`
}
```
- Environment variables use `UP_` prefix (defined in `ENVConfigPrefix`)
- Automatic unmarshaling via `golift.io/cnfg` and `golift.io/cnfgfile`
### Testing
- Tests in `_test` packages (enforced by `testpackage` linter)
- Use `github.com/stretchr/testify` for assertions
- Integration tests: `integration_test.go` with `integration_test_expectations.yaml`
## Key Dependencies
### Core Libraries
- `github.com/unpoller/unifi/v5` - UniFi API client (local: `/Users/briangates/unifi`)
- `golift.io/cnfg` - Configuration management
- `golift.io/cnfgfile` - Config file parsing
- `github.com/spf13/pflag` - CLI flags
- `github.com/gorilla/mux` - HTTP router
### Output Backends
- **InfluxDB**: `github.com/influxdata/influxdb1-client` (v1), `github.com/influxdata/influxdb-client-go/v2` (v2)
- **Prometheus**: `github.com/prometheus/client_golang`
- **DataDog**: `github.com/DataDog/datadog-go/v5`
- **Loki**: Custom HTTP implementation
## Data Structures
### Metrics
```go
type Metrics struct {
TS time.Time
Sites []any
Clients []any
SitesDPI []any
ClientsDPI []any
Devices []any
RogueAPs []any
SpeedTests []any
CountryTraffic []any
}
```
### Events
```go
type Events struct {
Logs []any
}
```
### Device Types
UniFi devices supported:
- **UAP** - Access Points (`uap.go`)
- **USG** - Security Gateways (`usg.go`)
- **USW** - Switches (`usw.go`)
- **UDM** - Dream Machines (`udm.go`)
- **UXG** - Next-Gen Gateways (`uxg.go`)
- **UBB** - Building Bridges (`ubb.go`)
- **UCI** - Industrial devices (`uci.go`)
- **PDU** - Power Distribution Units (`pdu.go`)
Each output plugin has device-specific reporting functions following the pattern:
```go
func (r *Report) UAP(uaps []*unifi.UAP) {
// Convert and export UAP data
}
```
## Common Development Tasks
### Adding a New Output Plugin
1. Create package in `pkg/myoutput/`
2. Implement `Output` interface
3. Register in `init()` function
4. Add blank import to `main.go`: `_ "github.com/unpoller/unpoller/pkg/myoutput"`
5. Add configuration struct with tags
6. Create `README.md` with usage examples
### Adding Device Type Support
1. Add device-specific file (e.g., `mydevice.go`)
2. Follow pattern from existing device files
3. Convert UniFi device struct to output format
4. Handle errors appropriately
### Modifying Configuration
1. Add fields to appropriate config struct
2. Include all format tags: `json`, `toml`, `xml`, `yaml`
3. Update example configs in `examples/`
4. Document in package `README.md`
## Build & Deployment
- **CI/CD**: GitHub Actions (`.github/workflows/`)
- **Build**: `goreleaser` (`.goreleaser.yaml`)
- **Platforms**: Linux, macOS, Windows, FreeBSD
- **Docker**: Auto-built to `ghcr.io`
- **Packages**: Debian, RedHat via goreleaser
- **Homebrew**: Formula for macOS
## Important Constraints
1. **Generic Core**: `pkg/poller` must remain generic - no UniFi/backend knowledge
2. **Cross-Platform**: Support Windows, macOS, Linux, BSD
3. **Configuration**: Support TOML (default), JSON, YAML, and environment variables
4. **Error Handling**: Always check and return errors
5. **Context**: Use `context.Context` for cancellable operations
6. **Timeouts**: Respect timeouts and deadlines
7. **Logging**: Use structured logging via logger interfaces
## Configuration Examples
**File Formats**: See `examples/up.conf.example`, `examples/up.json.example`, `examples/up.yaml.example`
**Environment Variables**:
```bash
UP_INFLUX_URL=http://localhost:8086
UP_UNIFI_DEFAULT_USER=admin
UP_UNIFI_DEFAULT_PASS=password
UP_POLLER_DEBUG=true
UP_POLLER_INTERVAL=30s
```
## When Writing Code
1. **Follow Existing Patterns**: Look at similar plugins for examples
2. **Keep Core Generic**: Don't add UniFi/backend-specific code to `pkg/poller`
3. **Error Handling**: Check all errors, return descriptive messages
4. **Documentation**: Document exported functions and types
5. **Testing**: Write tests in `_test` packages
6. **Cross-Platform**: Test on multiple platforms when possible
7. **Performance**: Consider polling intervals and data volume
8. **Security**: Don't log passwords or sensitive data
## Resources
- **Documentation**: https://unpoller.com
- **UniFi Library**: https://github.com/unpoller/unifi
- **Grafana Dashboards**: https://grafana.com/dashboards?search=unifi-poller
- **Discord**: https://golift.io/discord (#unpoller channel)
+241
View File
@@ -0,0 +1,241 @@
# UnPoller - Claude Code Context
## Project Overview
UnPoller is a Go application that collects metrics and events from UniFi network controllers and exports them to various time-series databases and monitoring systems. The application uses a plugin-based architecture where input plugins collect data and output plugins export it to different backends.
## Architecture
### Core Design Principles
1. **Plugin-Based Architecture**: The core `pkg/poller` library is generic and provides interfaces for input and output plugins. It has no knowledge of UniFi, InfluxDB, Prometheus, etc.
2. **Automatic Plugin Discovery**: Plugins are loaded via blank imports in `main.go`. The poller automatically discovers and initializes all imported plugins.
3. **Flexible Configuration**: Supports TOML (default), JSON, and YAML configuration files, plus environment variables with `UP_` prefix.
4. **Multiple Backends**: Supports InfluxDB, Prometheus, Loki, DataDog, and MySQL as output backends.
### Package Structure
```
pkg/
├── poller/ # Core plugin system - generic, no UniFi/backend knowledge
├── inputunifi/ # UniFi controller input plugin
├── influxunifi/ # InfluxDB output plugin
├── promunifi/ # Prometheus output plugin
├── lokiunifi/ # Loki output plugin
├── datadogunifi/ # DataDog output plugin
├── mysqlunifi/ # MySQL output plugin
└── webserver/ # Web server for health checks and metrics
```
### Key Interfaces
**Input Interface** (`pkg/poller/inputs.go`):
- `GetMetrics()` - Returns aggregated metrics
- `GetEvents()` - Returns events/logs
- Plugins must implement this to provide data
**Output Interface** (`pkg/poller/outputs.go`):
- `WriteMetrics()` - Writes metrics to backend
- `WriteEvents()` - Writes events to backend
- Plugins must implement this to export data
## Code Style Guidelines
### Go Conventions
- **Go Version**: 1.25.5+
- **Formatting**: Use `gofmt` standard formatting
- **Linting**: Follow `.golangci.yaml` configuration
- Enabled: `nlreturn`, `revive`, `tagalign`, `testpackage`, `wsl_v5`
- Use `//nolint:gci` for import ordering exceptions
### Naming
- **Packages**: Lowercase, single word
- **Exported**: PascalCase (types, functions, constants)
- **Unexported**: camelCase
- **Errors**: Always named `err`, checked immediately
### Error Handling
```go
// Good: Check and return errors
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
// Bad: Ignoring errors
_ = someFunction()
```
### Configuration Pattern
```go
type Config struct {
URL string `json:"url" toml:"url" yaml:"url"`
Interval string `json:"interval" toml:"interval" yaml:"interval"`
Timeout string `json:"timeout" toml:"timeout" yaml:"timeout"`
}
```
- Always include `json`, `toml`, `xml`, `yaml` tags
- Environment variables use `UP_` prefix automatically
- Use `golift.io/cnfg` for configuration management
### Testing
- Tests in separate `_test` packages (enforced by `testpackage` linter)
- Use `github.com/stretchr/testify` for assertions
- Integration tests use `integration_test_expectations.yaml`
## Common Tasks
### Adding a New Output Plugin
1. **Create Package Structure**:
```go
package myoutput
import (
"github.com/unpoller/unpoller/pkg/poller"
)
type Output struct {
// Configuration fields
}
func (o *Output) WriteMetrics(m *poller.Metrics) error {
// Implementation
}
func (o *Output) WriteEvents(e *poller.Events) error {
// Implementation
}
func init() {
poller.RegisterOutput(&Output{})
}
```
2. **Add Blank Import** to `main.go`:
```go
_ "github.com/unpoller/unpoller/pkg/myoutput"
```
3. **Add Configuration** to config structs with proper tags
4. **Create README.md** documenting usage
### Adding Device Type Support
Each output plugin has device-specific files:
- `uap.go` - Access Points
- `usg.go` - Security Gateways
- `usw.go` - Switches
- `udm.go` - Dream Machines
- `uxg.go` - Next-Gen Gateways
- `ubb.go` - Building Bridges
- `uci.go` - Industrial devices
- `pdu.go` - Power Distribution Units
Follow the pattern in existing files:
```go
func (r *Report) UAP(uaps []*unifi.UAP) {
// Convert UniFi device data to output format
}
```
### Working with UniFi Data
- UniFi library: `github.com/unpoller/unifi/v5` (local replace at `/Users/briangates/unifi`)
- Device types come from the UniFi controller API
- Data includes: sites, clients, devices, DPI data, speed tests, country traffic
- Events include: system logs, alarms, IDS events, anomalies
## Dependencies
### Core
- `github.com/unpoller/unifi/v5` - UniFi API client
- `golift.io/cnfg` - Configuration management
- `golift.io/cnfgfile` - Config file parsing
- `github.com/spf13/pflag` - CLI flags
### Output Backends
- InfluxDB: `github.com/influxdata/influxdb1-client` (v1) and `github.com/influxdata/influxdb-client-go/v2` (v2)
- Prometheus: `github.com/prometheus/client_golang`
- DataDog: `github.com/DataDog/datadog-go/v5`
- Loki: Custom HTTP client implementation
## Important Patterns
### Plugin Registration
```go
func init() {
poller.RegisterInput(&Input{})
// or
poller.RegisterOutput(&Output{})
}
```
### Configuration Loading
Configuration is automatically loaded from:
1. Config file (TOML/JSON/YAML) - path specified via `--config` flag or defaults
2. Environment variables with `UP_` prefix
3. CLI flags
### Metrics Structure
```go
type Metrics struct {
TS time.Time
Sites []any
Clients []any
SitesDPI []any
ClientsDPI []any
Devices []any
RogueAPs []any
SpeedTests []any
CountryTraffic []any
}
```
### Events Structure
```go
type Events struct {
Logs []any
}
```
## Build & Deployment
- **CI/CD**: GitHub Actions
- **Build Tool**: `goreleaser` for multi-platform builds
- **Platforms**: Linux, macOS, Windows, FreeBSD
- **Docker**: Images built automatically to `ghcr.io`
- **Homebrew**: Formula for macOS users
- **Packages**: Debian, RedHat packages via goreleaser
## When Writing Code
1. **Keep it Generic**: The `pkg/poller` core should remain generic
2. **Follow Patterns**: Look at existing plugins for examples
3. **Error Handling**: Always check and return errors
4. **Cross-Platform**: Consider Windows, macOS, Linux, BSD differences
5. **Context Usage**: Use `context.Context` for cancellable operations
6. **Timeouts**: Respect timeouts and deadlines
7. **Documentation**: Document exported functions and types
8. **Testing**: Write tests in separate `_test` packages
## Configuration Examples
Configuration files support multiple formats. See `examples/` directory:
- `up.conf.example` - TOML format
- `up.json.example` - JSON format
- `up.yaml.example` - YAML format
Environment variables use `UP_` prefix:
- `UP_INFLUX_URL=http://localhost:8086`
- `UP_UNIFI_DEFAULT_USER=admin`
- `UP_POLLER_DEBUG=true`