mirror of
https://github.com/SigNoz/signoz.git
synced 2026-08-09 06:30:37 +01:00
primus bumped golangci-lint to v2.12.2, whose govet now runs the inline analyzer and whose sloglint is stricter. CI resolves primus.workflows@main, so every PR started failing lint the moment that landed. - reflect.Ptr is a deprecated alias carrying //go:fix inline, so it is now reflect.Pointer at all five call sites - metricsstatementbuilder imported golang.org/x/exp/slices, which carries //go:fix inline pointing at the stdlib; the analyzer cannot inline generics, so switch the import to stdlib slices as the directive intends - pkg/instrumentation/loghandler emits OpenTelemetry semantic-convention attributes (code.filepath, exception.type, ...), which are dotted rather than snake_case by definition. Renaming them would break every log consumer, so the keys move to constants in instrumentationtypes, which already held this kind of key -- and already defined code.function, so source.go was duplicating it. Six of the seven alias the semconv constants that define them; exception.code has no OTel equivalent. sloglint resolves a same-package constant back to its literal but skips a qualified one, so this needs no exclusion. CI reported 8 issues but capped at max-same-issues=3, hiding 2 more reflect.Ptr sites and 4 more sloglint ones. Separately, TestTimeout/WaitTillNoTimeoutForExcludedPath failed with "transport connection broken: http: CloseIdleConnections called". TestTimeout and TestCache issue requests through http.DefaultClient while a parallel subtest in response_test.go closes an httptest.Server, and httptest.Server.Close calls http.DefaultTransport.CloseIdleConnections. Both tests now use their own client and transport, and are closed via t.Cleanup. That makes Serve return ErrServerClosed on every run, so the require.NoError wrapping it is dropped -- it could never have held, and require runs t.FailNow off the test goroutine anyway. Bare Serve in a goroutine matches routerweb and render tests.
182 lines
3.3 KiB
Go
182 lines
3.3 KiB
Go
package querier
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
func toStrArrayString(strs ...string) string {
|
|
return fmt.Sprintf("[%s]", strings.Join(strs, ","))
|
|
}
|
|
|
|
// formatValue formats the value to be used in clickhouse query.
|
|
func formatValueForCH(v any) string {
|
|
// if it's pointer convert it to a value
|
|
v = getPointerValue(v)
|
|
|
|
switch x := v.(type) {
|
|
case uint8, uint16, uint32, uint64, int, int8, int16, int32, int64:
|
|
return fmt.Sprintf("%d", x)
|
|
case float32, float64:
|
|
return fmt.Sprintf("%f", x)
|
|
case string:
|
|
return fmt.Sprintf("'%s'", quoteEscapedString(x))
|
|
case bool:
|
|
return fmt.Sprintf("%v", x)
|
|
|
|
case []any:
|
|
if len(x) == 0 {
|
|
return "[]"
|
|
}
|
|
switch x[0].(type) {
|
|
case string:
|
|
strs := []string{}
|
|
for _, sVal := range x {
|
|
strs = append(strs, fmt.Sprintf("'%s'", quoteEscapedString(sVal.(string))))
|
|
}
|
|
return toStrArrayString(strs...)
|
|
case uint8, uint16, uint32, uint64, int, int8, int16, int32, int64, float32, float64, bool:
|
|
return strings.Join(strings.Fields(fmt.Sprint(x)), ",")
|
|
default:
|
|
return toStrArrayString()
|
|
}
|
|
case []string:
|
|
strs := []string{}
|
|
for _, sVal := range x {
|
|
strs = append(strs, fmt.Sprintf("'%s'", quoteEscapedString(sVal)))
|
|
}
|
|
return toStrArrayString(strs...)
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func getPointerValue(v any) any {
|
|
|
|
// Check if the interface value is nil
|
|
if v == nil {
|
|
return nil
|
|
}
|
|
|
|
// Use reflection to check if the pointer is nil
|
|
rv := reflect.ValueOf(v)
|
|
if rv.Kind() == reflect.Pointer && rv.IsNil() {
|
|
return nil
|
|
}
|
|
|
|
switch x := v.(type) {
|
|
case *uint8:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *uint16:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *uint32:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *uint64:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *int:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *int8:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *int16:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *int32:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *int64:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *float32:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *float64:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *string:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case *bool:
|
|
if x == nil {
|
|
return nil
|
|
}
|
|
return *x
|
|
case []any:
|
|
values := []any{}
|
|
for _, val := range x {
|
|
values = append(values, getPointerValue(val))
|
|
}
|
|
return values
|
|
default:
|
|
return v
|
|
}
|
|
}
|
|
|
|
func quoteEscapedString(str string) string {
|
|
// https://clickhouse.com/docs/en/sql-reference/syntax#string
|
|
str = strings.ReplaceAll(str, `\`, `\\`)
|
|
str = strings.ReplaceAll(str, `'`, `\'`)
|
|
return str
|
|
}
|
|
|
|
// formatValueForProm formats the value to be used in promql.
|
|
func formatValueForProm(v any) string {
|
|
switch x := v.(type) {
|
|
case int:
|
|
return fmt.Sprintf("%d", x)
|
|
case float32, float64:
|
|
return fmt.Sprintf("%f", x)
|
|
case string:
|
|
return x
|
|
case bool:
|
|
return fmt.Sprintf("%v", x)
|
|
case []interface{}:
|
|
if len(x) == 0 {
|
|
return ""
|
|
}
|
|
switch x[0].(type) {
|
|
case string, int, float32, float64, bool:
|
|
// list of values joined by | for promql - a value can contain whitespace
|
|
var str []string
|
|
for _, sVal := range x {
|
|
str = append(str, fmt.Sprintf("%v", sVal))
|
|
}
|
|
return strings.Join(str, "|")
|
|
default:
|
|
return ""
|
|
}
|
|
default:
|
|
return ""
|
|
}
|
|
}
|