mirror of
https://github.com/SigNoz/signoz.git
synced 2026-06-15 21:20:28 +01:00
Compare commits
4 Commits
nv/schema-
...
issue_4360
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17afadfee8 | ||
|
|
c55c2ab218 | ||
|
|
f48ea7f406 | ||
|
|
dfa49b7bd7 |
@@ -106,7 +106,7 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
|
||||
// initiate agent config handler
|
||||
agentConfMgr, err := agentConf.Initiate(&agentConf.ManagerOptions{
|
||||
Store: signoz.SQLStore,
|
||||
AgentFeatures: []agentConf.AgentFeature{logParsingPipelineController},
|
||||
AgentFeatures: []agentConf.AgentFeature{logParsingPipelineController, signoz.Modules.LLMPricingRule},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -128,6 +128,7 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
|
||||
Store: signoz.SQLStore,
|
||||
AgentFeatures: []agentConf.AgentFeature{
|
||||
logParsingPipelineController,
|
||||
signoz.Modules.LLMPricingRule,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
@@ -53,7 +53,8 @@ var (
|
||||
LLMPricingRuleCacheModeSubtract = LLMPricingRuleCacheMode{valuer.NewString("subtract")}
|
||||
// LLMPricingRuleCacheModeAdditive: cached tokens are reported separately (Anthropic-style).
|
||||
LLMPricingRuleCacheModeAdditive = LLMPricingRuleCacheMode{valuer.NewString("additive")}
|
||||
// LLMPricingRuleCacheModeUnknown: provider behaviour is unknown; falls back to subtract.
|
||||
// LLMPricingRuleCacheModeUnknown: provider behaviour is unknown. buildProcessorConfig
|
||||
// normalizes this to an empty mode in the collector config.
|
||||
LLMPricingRuleCacheModeUnknown = LLMPricingRuleCacheMode{valuer.NewString("unknown")}
|
||||
)
|
||||
|
||||
|
||||
@@ -26,24 +26,23 @@ type LLMPricingRuleProcessorAttrs struct {
|
||||
CacheWrite string `yaml:"cache_write" json:"cache_write"`
|
||||
}
|
||||
|
||||
// LLMPricingRuleProcessorDefaultPricing holds the pricing unit and the list of model-specific rules.
|
||||
// LLMPricingRuleProcessorDefaultPricing holds the list of model-specific rules.
|
||||
type LLMPricingRuleProcessorDefaultPricing struct {
|
||||
Unit string `yaml:"unit" json:"unit"`
|
||||
Rules []LLMPricingRuleProcessor `yaml:"rules" json:"rules"`
|
||||
}
|
||||
|
||||
// LLMPricingRuleProcessor is a single pricing rule inside the processor config.
|
||||
type LLMPricingRuleProcessor struct {
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Pattern []string `yaml:"pattern" json:"pattern"`
|
||||
Cache LLMPricingRuleProcessorCache `yaml:"cache" json:"cache"`
|
||||
In float64 `yaml:"in" json:"in"`
|
||||
Out float64 `yaml:"out" json:"out"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Pattern []string `yaml:"pattern" json:"pattern"`
|
||||
Cache *LLMPricingRuleProcessorCache `yaml:"cache,omitempty" json:"cache,omitempty"`
|
||||
In float64 `yaml:"in" json:"in"`
|
||||
Out float64 `yaml:"out" json:"out"`
|
||||
}
|
||||
|
||||
// LLMPricingRuleProcessorCache describes how cached tokens are accounted for.
|
||||
type LLMPricingRuleProcessorCache struct {
|
||||
Mode string `yaml:"mode" json:"mode"`
|
||||
Mode string `yaml:"mode,omitempty" json:"mode,omitempty"`
|
||||
Read float64 `yaml:"read" json:"read"`
|
||||
Write float64 `yaml:"write" json:"write"`
|
||||
}
|
||||
@@ -61,10 +60,14 @@ type LLMPricingRuleProcessorOutputAttrs struct {
|
||||
func buildProcessorConfig(rules []*LLMPricingRule) *LLMPricingRuleProcessorConfig {
|
||||
pricingRules := make([]LLMPricingRuleProcessor, 0, len(rules))
|
||||
for _, r := range rules {
|
||||
var cache LLMPricingRuleProcessorCache
|
||||
var cache *LLMPricingRuleProcessorCache
|
||||
if r.Pricing.Cache != nil {
|
||||
cache = LLMPricingRuleProcessorCache{
|
||||
Mode: r.Pricing.Cache.Mode.StringValue(),
|
||||
mode := r.Pricing.Cache.Mode.StringValue()
|
||||
if mode != LLMPricingRuleCacheModeSubtract.StringValue() && mode != LLMPricingRuleCacheModeAdditive.StringValue() {
|
||||
mode = ""
|
||||
}
|
||||
cache = &LLMPricingRuleProcessorCache{
|
||||
Mode: mode,
|
||||
Read: r.Pricing.Cache.Read,
|
||||
Write: r.Pricing.Cache.Write,
|
||||
}
|
||||
@@ -87,7 +90,6 @@ func buildProcessorConfig(rules []*LLMPricingRule) *LLMPricingRuleProcessorConfi
|
||||
CacheWrite: GenAIUsageCacheCreationInputTokens,
|
||||
},
|
||||
DefaultPricing: LLMPricingRuleProcessorDefaultPricing{
|
||||
Unit: UnitPerMillionTokens.StringValue(),
|
||||
Rules: pricingRules,
|
||||
},
|
||||
OutputAttrs: LLMPricingRuleProcessorOutputAttrs{
|
||||
|
||||
@@ -41,6 +41,16 @@ func makePricingRule(model string, patterns []string, cacheMode LLMPricingRuleCa
|
||||
}
|
||||
}
|
||||
|
||||
func makePricingRuleNoCache(model string, patterns []string, costIn, costOut float64) *LLMPricingRule {
|
||||
return &LLMPricingRule{
|
||||
Model: model,
|
||||
ModelPattern: StringSlice(patterns),
|
||||
Unit: UnitPerMillionTokens,
|
||||
Pricing: LLMRulePricing{Input: costIn, Output: costOut},
|
||||
Enabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCollectorConfigWithLLMPricingProcessor(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -62,6 +72,24 @@ func TestGenerateCollectorConfigWithLLMPricingProcessor(t *testing.T) {
|
||||
rules: nil,
|
||||
expectedFile: "collector_no_rules.yaml",
|
||||
},
|
||||
// A rule without cache pricing omits the cache block entirely so the
|
||||
// collector does not apply any cache cost.
|
||||
{
|
||||
name: "rule_without_cache",
|
||||
rules: []*LLMPricingRule{
|
||||
makePricingRuleNoCache("gpt-4o", []string{"gpt-4o*"}, 5.0, 15.0),
|
||||
},
|
||||
expectedFile: "collector_rule_without_cache.yaml",
|
||||
},
|
||||
// An unknown cache mode still emits the cache block (with prices) but omits
|
||||
// the mode field; the collector handles a missing mode in its default branch.
|
||||
{
|
||||
name: "rule_cache_mode_unknown",
|
||||
rules: []*LLMPricingRule{
|
||||
makePricingRule("gpt-4o", []string{"gpt-4o*"}, LLMPricingRuleCacheModeUnknown, 5.0, 15.0, 2.5, 0),
|
||||
},
|
||||
expectedFile: "collector_rule_cache_mode_unknown.yaml",
|
||||
},
|
||||
}
|
||||
|
||||
input, err := os.ReadFile(filepath.Join("testdata", "collector_baseline.yaml"))
|
||||
|
||||
@@ -11,7 +11,6 @@ processors:
|
||||
cache_read: gen_ai.usage.cache_read.input_tokens
|
||||
cache_write: gen_ai.usage.cache_creation.input_tokens
|
||||
default_pricing:
|
||||
unit: per_million_tokens
|
||||
rules: []
|
||||
output_attrs:
|
||||
in: _signoz.gen_ai.cost_input
|
||||
|
||||
@@ -11,7 +11,6 @@ processors:
|
||||
cache_read: gen_ai.usage.cache_read.input_tokens
|
||||
cache_write: gen_ai.usage.cache_creation.input_tokens
|
||||
default_pricing:
|
||||
unit: per_million_tokens
|
||||
rules: []
|
||||
output_attrs:
|
||||
in: _signoz.gen_ai.cost_input
|
||||
|
||||
42
pkg/types/llmpricingruletypes/testdata/collector_rule_cache_mode_unknown.yaml
vendored
Normal file
42
pkg/types/llmpricingruletypes/testdata/collector_rule_cache_mode_unknown.yaml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
exporters:
|
||||
otlp:
|
||||
endpoint: localhost:4317
|
||||
processors:
|
||||
batch: {}
|
||||
signozllmpricing:
|
||||
attrs:
|
||||
model: gen_ai.request.model
|
||||
in: gen_ai.usage.input_tokens
|
||||
out: gen_ai.usage.output_tokens
|
||||
cache_read: gen_ai.usage.cache_read.input_tokens
|
||||
cache_write: gen_ai.usage.cache_creation.input_tokens
|
||||
default_pricing:
|
||||
rules:
|
||||
- name: gpt-4o
|
||||
pattern:
|
||||
- gpt-4o*
|
||||
cache:
|
||||
read: 2.5
|
||||
write: 0
|
||||
in: 5
|
||||
out: 15
|
||||
output_attrs:
|
||||
in: _signoz.gen_ai.cost_input
|
||||
out: _signoz.gen_ai.cost_output
|
||||
cache_read: _signoz.gen_ai.cost_cache_read
|
||||
cache_write: _signoz.gen_ai.cost_cache_write
|
||||
total: _signoz.gen_ai.total_cost
|
||||
receivers:
|
||||
otlp:
|
||||
protocols:
|
||||
grpc: null
|
||||
service:
|
||||
pipelines:
|
||||
traces:
|
||||
exporters:
|
||||
- otlp
|
||||
processors:
|
||||
- batch
|
||||
- signozllmpricing
|
||||
receivers:
|
||||
- otlp
|
||||
39
pkg/types/llmpricingruletypes/testdata/collector_rule_without_cache.yaml
vendored
Normal file
39
pkg/types/llmpricingruletypes/testdata/collector_rule_without_cache.yaml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
exporters:
|
||||
otlp:
|
||||
endpoint: localhost:4317
|
||||
processors:
|
||||
batch: {}
|
||||
signozllmpricing:
|
||||
attrs:
|
||||
model: gen_ai.request.model
|
||||
in: gen_ai.usage.input_tokens
|
||||
out: gen_ai.usage.output_tokens
|
||||
cache_read: gen_ai.usage.cache_read.input_tokens
|
||||
cache_write: gen_ai.usage.cache_creation.input_tokens
|
||||
default_pricing:
|
||||
rules:
|
||||
- name: gpt-4o
|
||||
pattern:
|
||||
- gpt-4o*
|
||||
in: 5
|
||||
out: 15
|
||||
output_attrs:
|
||||
in: _signoz.gen_ai.cost_input
|
||||
out: _signoz.gen_ai.cost_output
|
||||
cache_read: _signoz.gen_ai.cost_cache_read
|
||||
cache_write: _signoz.gen_ai.cost_cache_write
|
||||
total: _signoz.gen_ai.total_cost
|
||||
receivers:
|
||||
otlp:
|
||||
protocols:
|
||||
grpc: null
|
||||
service:
|
||||
pipelines:
|
||||
traces:
|
||||
exporters:
|
||||
- otlp
|
||||
processors:
|
||||
- batch
|
||||
- signozllmpricing
|
||||
receivers:
|
||||
- otlp
|
||||
@@ -11,7 +11,6 @@ processors:
|
||||
cache_read: gen_ai.usage.cache_read.input_tokens
|
||||
cache_write: gen_ai.usage.cache_creation.input_tokens
|
||||
default_pricing:
|
||||
unit: per_million_tokens
|
||||
rules:
|
||||
- name: gpt-4o
|
||||
pattern:
|
||||
|
||||
Reference in New Issue
Block a user