11import { SECRET } from "./secret"
22import { domain } from "./stage"
33
4+ const description = "Managed by SST (Don't edit in Honeycomb UI)"
5+
46const webhookRecipient = new honeycomb . WebhookRecipient ( "DiscordAlerts" , {
57 name : $app . stage === "production" ? "Discord Alerts" : `Discord Alerts (${ $app . stage } )` ,
68 url : `https://${ domain } /honeycomb/webhook` ,
@@ -25,28 +27,43 @@ const webhookRecipient = new honeycomb.WebhookRecipient("DiscordAlerts", {
2527 ] ,
2628} )
2729
30+ // Honeycomb can keep stale query-local calculated fields when the name is unchanged,
31+ // so tie the field name to the expression while avoiding deploy-to-deploy churn.
32+ // https://github.com/honeycombio/terraform-provider-honeycombio/issues/852
33+ const calculatedField = ( field : { name : string ; expression : string } ) => ( {
34+ ...field ,
35+ name : `${ field . name } _${ (
36+ Array . from ( field . expression ) . reduce ( ( result , char ) => Math . imul ( 31 , result ) + char . charCodeAt ( 0 ) , 0 ) >>> 0
37+ ) . toString ( 36 ) } `,
38+ } )
39+
2840const modelHttpErrorsQuery = ( product : "go" | "zen" ) => {
2941 const filters = [
3042 { column : "model" , op : "exists" } ,
3143 { column : "event_type" , op : "=" , value : "completions" } ,
3244 { column : "user_agent" , op : "contains" , value : "opencode" } ,
3345 { column : "isGoTier" , op : "=" , value : product === "go" ? "true" : "false" } ,
3446 ]
47+ const failedHttpStatus = calculatedField ( {
48+ name : "is_failed_http_status" ,
49+ expression :
50+ product === "go"
51+ ? `IF(AND(GTE($status, "400"), NOT(EQUALS($status, "401")), NOT(EQUALS($status, "429"))), 1, 0)`
52+ : `IF(AND(EQUALS($status, "429"), $isFreeTier), 0, AND(GTE($status, "400"), NOT(EQUALS($status, "401"))), 1, 0)` ,
53+ } )
3554
3655 return honeycomb . getQuerySpecificationOutput ( {
3756 breakdowns : [ "model" ] ,
38- calculatedFields : [
39- {
40- name : "is_failed_http_status" ,
41- expression :
42- product === "go"
43- ? `IF(AND(GTE($status, "400"), NOT(EQUALS($status, "401")), NOT(EQUALS($status, "429"))), 1, 0)`
44- : `IF(AND(GTE($status, "400"), NOT(EQUALS($status, "401"))), 1, 0)` ,
45- } ,
46- ] ,
57+ calculatedFields : [ failedHttpStatus ] ,
4758 calculations : [
4859 { op : "COUNT" , name : "TOTAL" , filterCombination : "AND" , filters } ,
49- { op : "SUM" , name : "FAILED" , column : "is_failed_http_status" , filterCombination : "AND" , filters } ,
60+ {
61+ op : "SUM" ,
62+ name : "FAILED" ,
63+ column : failedHttpStatus . name ,
64+ filterCombination : "AND" ,
65+ filters,
66+ } ,
5067 ] ,
5168 formulas : [ { name : "ERROR" , expression : "IF(GTE($TOTAL, 100), DIV($FAILED, $TOTAL), 0)" } ] ,
5269 timeRange : 900 ,
@@ -59,31 +76,30 @@ const providerHttpErrorsQuery = (product: "go" | "zen") => {
5976 { column : "user_agent" , op : "contains" , value : "opencode" } ,
6077 { column : "isGoTier" , op : "=" , value : product === "go" ? "true" : "false" } ,
6178 ]
79+ const successHttpStatus = calculatedField ( {
80+ name : "is_success_http_status" ,
81+ expression : `IF(AND(GTE($status, "200"), LT($status, "400")), 1, 0)` ,
82+ } )
83+ const failedProviderHttpStatus = calculatedField ( {
84+ name : "is_failed_provider_http_status" ,
85+ expression : `IF(GT($llm.error.code, "400"), 1, 0)` ,
86+ } )
6287
6388 return honeycomb . getQuerySpecificationOutput ( {
6489 breakdowns : [ "provider" ] ,
65- calculatedFields : [
66- {
67- name : "is_success_http_status" ,
68- expression : `IF(AND(GTE($status, "200"), LT($status, "400")), 1, 0)` ,
69- } ,
70- {
71- name : "is_failed_provider_http_status" ,
72- expression : `IF(GT($llm.error.code, "400"), 1, 0)` ,
73- } ,
74- ] ,
90+ calculatedFields : [ successHttpStatus , failedProviderHttpStatus ] ,
7591 calculations : [
7692 {
7793 op : "SUM" ,
7894 name : "SUCCESS" ,
79- column : "is_success_http_status" ,
95+ column : successHttpStatus . name ,
8096 filterCombination : "AND" ,
8197 filters : [ ...filters , { column : "event_type" , op : "=" , value : "completions" } ] ,
8298 } ,
8399 {
84100 op : "SUM" ,
85101 name : "FAILED" ,
86- column : "is_failed_provider_http_status" ,
102+ column : failedProviderHttpStatus . name ,
87103 filterCombination : "AND" ,
88104 filters : [ ...filters , { column : "event_type" , op : "=" , value : "llm.error" } ] ,
89105 } ,
@@ -95,8 +111,6 @@ const providerHttpErrorsQuery = (product: "go" | "zen") => {
95111 } ) . json
96112}
97113
98- const description = "Managed by SST (Don't edit in Honeycomb UI)"
99-
100114new honeycomb . Trigger ( "IncreasedModelHttpErrorsGo" , {
101115 name : "Increased Model HTTP Errors [Go]" ,
102116 description,
0 commit comments