Major security, observability, and configuration improvements:
## Security Hardening
- Implemented configurable CORS (no more wildcards)
- Added comprehensive auth middleware for admin endpoints
- Enhanced webhook HMAC validation
- Added input validation and rate limiting
- Security headers and CSP policies
## Configuration Management
- Made N8N webhook URL configurable (WHOOSH_N8N_BASE_URL)
- Replaced all hardcoded endpoints with environment variables
- Added feature flags for LLM vs heuristic composition
- Gitea fetch hardening with EAGER_FILTER and FULL_RESCAN options
## API Completeness
- Implemented GetCouncilComposition function
- Added GET /api/v1/councils/{id} endpoint
- Council artifacts API (POST/GET /api/v1/councils/{id}/artifacts)
- /admin/health/details endpoint with component status
- Database lookup for repository URLs (no hardcoded fallbacks)
## Observability & Performance
- Added OpenTelemetry distributed tracing with goal/pulse correlation
- Performance optimization database indexes
- Comprehensive health monitoring
- Enhanced logging and error handling
## Infrastructure
- Production-ready P2P discovery (replaces mock implementation)
- Removed unused Redis configuration
- Enhanced Docker Swarm integration
- Added migration files for performance indexes
## Code Quality
- Comprehensive input validation
- Graceful error handling and failsafe fallbacks
- Backwards compatibility maintained
- Following security best practices
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
109 lines
2.9 KiB
Go
109 lines
2.9 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package trace // import "go.opentelemetry.io/otel/sdk/trace"
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
tracesSamplerKey = "OTEL_TRACES_SAMPLER"
|
|
tracesSamplerArgKey = "OTEL_TRACES_SAMPLER_ARG"
|
|
|
|
samplerAlwaysOn = "always_on"
|
|
samplerAlwaysOff = "always_off"
|
|
samplerTraceIDRatio = "traceidratio"
|
|
samplerParentBasedAlwaysOn = "parentbased_always_on"
|
|
samplerParsedBasedAlwaysOff = "parentbased_always_off"
|
|
samplerParentBasedTraceIDRatio = "parentbased_traceidratio"
|
|
)
|
|
|
|
type errUnsupportedSampler string
|
|
|
|
func (e errUnsupportedSampler) Error() string {
|
|
return fmt.Sprintf("unsupported sampler: %s", string(e))
|
|
}
|
|
|
|
var (
|
|
errNegativeTraceIDRatio = errors.New("invalid trace ID ratio: less than 0.0")
|
|
errGreaterThanOneTraceIDRatio = errors.New("invalid trace ID ratio: greater than 1.0")
|
|
)
|
|
|
|
type samplerArgParseError struct {
|
|
parseErr error
|
|
}
|
|
|
|
func (e samplerArgParseError) Error() string {
|
|
return fmt.Sprintf("parsing sampler argument: %s", e.parseErr.Error())
|
|
}
|
|
|
|
func (e samplerArgParseError) Unwrap() error {
|
|
return e.parseErr
|
|
}
|
|
|
|
func samplerFromEnv() (Sampler, error) {
|
|
sampler, ok := os.LookupEnv(tracesSamplerKey)
|
|
if !ok {
|
|
return nil, nil
|
|
}
|
|
|
|
sampler = strings.ToLower(strings.TrimSpace(sampler))
|
|
samplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey)
|
|
samplerArg = strings.TrimSpace(samplerArg)
|
|
|
|
switch sampler {
|
|
case samplerAlwaysOn:
|
|
return AlwaysSample(), nil
|
|
case samplerAlwaysOff:
|
|
return NeverSample(), nil
|
|
case samplerTraceIDRatio:
|
|
if !hasSamplerArg {
|
|
return TraceIDRatioBased(1.0), nil
|
|
}
|
|
return parseTraceIDRatio(samplerArg)
|
|
case samplerParentBasedAlwaysOn:
|
|
return ParentBased(AlwaysSample()), nil
|
|
case samplerParsedBasedAlwaysOff:
|
|
return ParentBased(NeverSample()), nil
|
|
case samplerParentBasedTraceIDRatio:
|
|
if !hasSamplerArg {
|
|
return ParentBased(TraceIDRatioBased(1.0)), nil
|
|
}
|
|
ratio, err := parseTraceIDRatio(samplerArg)
|
|
return ParentBased(ratio), err
|
|
default:
|
|
return nil, errUnsupportedSampler(sampler)
|
|
}
|
|
}
|
|
|
|
func parseTraceIDRatio(arg string) (Sampler, error) {
|
|
v, err := strconv.ParseFloat(arg, 64)
|
|
if err != nil {
|
|
return TraceIDRatioBased(1.0), samplerArgParseError{err}
|
|
}
|
|
if v < 0.0 {
|
|
return TraceIDRatioBased(1.0), errNegativeTraceIDRatio
|
|
}
|
|
if v > 1.0 {
|
|
return TraceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio
|
|
}
|
|
|
|
return TraceIDRatioBased(v), nil
|
|
}
|