2022-10-06 20:13:30 +05:30
package main
import (
"context"
"flag"
2023-06-21 11:47:30 +05:30
"log"
2022-10-06 20:13:30 +05:30
"os"
"os/signal"
2023-06-21 11:47:30 +05:30
"strconv"
2022-10-06 20:13:30 +05:30
"syscall"
2023-06-21 11:47:30 +05:30
"time"
2022-10-06 20:13:30 +05:30
2023-06-21 11:47:30 +05:30
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
2022-10-06 20:13:30 +05:30
"go.signoz.io/signoz/ee/query-service/app"
2025-01-20 17:45:33 +05:30
"go.signoz.io/signoz/pkg/config"
"go.signoz.io/signoz/pkg/config/envprovider"
"go.signoz.io/signoz/pkg/config/fileprovider"
2022-10-06 20:13:30 +05:30
"go.signoz.io/signoz/pkg/query-service/auth"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
2024-05-17 07:45:03 +05:30
"go.signoz.io/signoz/pkg/query-service/migrate"
2022-10-06 20:13:30 +05:30
"go.signoz.io/signoz/pkg/query-service/version"
2025-01-04 01:28:54 +05:30
"go.signoz.io/signoz/pkg/signoz"
2023-06-21 11:47:30 +05:30
"google.golang.org/grpc"
2024-03-27 00:07:29 +05:30
"google.golang.org/grpc/credentials/insecure"
2023-06-21 11:47:30 +05:30
2024-10-10 14:10:28 +05:30
prommodel "github.com/prometheus/common/model"
2023-06-21 11:47:30 +05:30
zapotlpencoder "github.com/SigNoz/zap_otlp/zap_otlp_encoder"
zapotlpsync "github.com/SigNoz/zap_otlp/zap_otlp_sync"
2022-10-06 20:13:30 +05:30
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
2023-06-21 11:47:30 +05:30
func initZapLog ( enableQueryServiceLogOTLPExport bool ) * zap . Logger {
2024-03-27 00:07:29 +05:30
config := zap . NewProductionConfig ( )
2023-06-21 11:47:30 +05:30
ctx , stop := signal . NotifyContext ( context . Background ( ) , os . Interrupt )
defer stop ( )
2024-03-27 00:07:29 +05:30
config . EncoderConfig . EncodeDuration = zapcore . MillisDurationEncoder
config . EncoderConfig . EncodeLevel = zapcore . CapitalLevelEncoder
2022-10-06 20:13:30 +05:30
config . EncoderConfig . TimeKey = "timestamp"
config . EncoderConfig . EncodeTime = zapcore . ISO8601TimeEncoder
2023-06-21 11:47:30 +05:30
2024-03-27 00:07:29 +05:30
otlpEncoder := zapotlpencoder . NewOTLPEncoder ( config . EncoderConfig )
consoleEncoder := zapcore . NewJSONEncoder ( config . EncoderConfig )
defaultLogLevel := zapcore . InfoLevel
2023-06-21 11:47:30 +05:30
res := resource . NewWithAttributes (
semconv . SchemaURL ,
semconv . ServiceNameKey . String ( "query-service" ) ,
)
core := zapcore . NewTee (
zapcore . NewCore ( consoleEncoder , os . Stdout , defaultLogLevel ) ,
)
2024-03-27 00:07:29 +05:30
if enableQueryServiceLogOTLPExport {
2024-06-11 20:10:38 +05:30
ctx , cancel := context . WithTimeout ( ctx , time . Second * 30 )
defer cancel ( )
2024-03-27 00:07:29 +05:30
conn , err := grpc . DialContext ( ctx , baseconst . OTLPTarget , grpc . WithBlock ( ) , grpc . WithTransportCredentials ( insecure . NewCredentials ( ) ) )
2023-06-21 11:47:30 +05:30
if err != nil {
2024-03-27 00:07:29 +05:30
log . Fatalf ( "failed to establish connection: %v" , err )
2023-06-21 11:47:30 +05:30
} else {
logExportBatchSizeInt , err := strconv . Atoi ( baseconst . LogExportBatchSize )
if err != nil {
2024-03-27 00:07:29 +05:30
logExportBatchSizeInt = 512
2023-06-21 11:47:30 +05:30
}
ws := zapcore . AddSync ( zapotlpsync . NewOtlpSyncer ( conn , zapotlpsync . Options {
BatchSize : logExportBatchSizeInt ,
ResourceSchema : semconv . SchemaURL ,
Resource : res ,
} ) )
core = zapcore . NewTee (
zapcore . NewCore ( consoleEncoder , os . Stdout , defaultLogLevel ) ,
zapcore . NewCore ( otlpEncoder , zapcore . NewMultiWriteSyncer ( ws ) , defaultLogLevel ) ,
)
}
}
logger := zap . New ( core , zap . AddCaller ( ) , zap . AddStacktrace ( zapcore . ErrorLevel ) )
2022-10-06 20:13:30 +05:30
return logger
}
2024-10-10 14:10:28 +05:30
func init ( ) {
prommodel . NameValidationScheme = prommodel . UTF8Validation
}
2022-10-06 20:13:30 +05:30
func main ( ) {
2023-06-30 06:58:22 +05:30
var promConfigPath , skipTopLvlOpsPath string
2022-10-06 20:13:30 +05:30
// disables rule execution but allows change to the rule definition
var disableRules bool
// the url used to build link in the alert messages in slack and other systems
var ruleRepoURL string
2023-10-20 12:37:45 +05:30
var cluster string
2022-10-06 20:13:30 +05:30
2024-09-12 10:58:07 +05:30
var useLogsNewSchema bool
2024-11-22 12:00:29 +05:30
var useTraceNewSchema bool
2025-01-24 00:16:38 +05:30
var cacheConfigPath , fluxInterval , fluxIntervalForTraceDetail string
2023-06-21 11:47:30 +05:30
var enableQueryServiceLogOTLPExport bool
2023-07-14 11:31:44 +05:30
var preferSpanMetrics bool
2023-06-21 11:47:30 +05:30
2023-08-10 17:20:34 +05:30
var maxIdleConns int
var maxOpenConns int
var dialTimeout time . Duration
2024-06-04 18:25:24 +05:30
var gatewayUrl string
2024-12-17 01:12:31 +05:30
var useLicensesV3 bool
2023-08-10 17:20:34 +05:30
2024-09-12 10:58:07 +05:30
flag . BoolVar ( & useLogsNewSchema , "use-logs-new-schema" , false , "use logs_v2 schema for logs" )
2024-11-22 12:00:29 +05:30
flag . BoolVar ( & useTraceNewSchema , "use-trace-new-schema" , false , "use new schema for traces" )
2022-10-06 20:13:30 +05:30
flag . StringVar ( & promConfigPath , "config" , "./config/prometheus.yml" , "(prometheus config to read metrics)" )
2023-06-30 06:58:22 +05:30
flag . StringVar ( & skipTopLvlOpsPath , "skip-top-level-ops" , "" , "(config file to skip top level operations)" )
2022-10-06 20:13:30 +05:30
flag . BoolVar ( & disableRules , "rules.disable" , false , "(disable rule evaluation)" )
2023-07-14 11:31:44 +05:30
flag . BoolVar ( & preferSpanMetrics , "prefer-span-metrics" , false , "(prefer span metrics for service level metrics)" )
2023-08-10 17:20:34 +05:30
flag . IntVar ( & maxIdleConns , "max-idle-conns" , 50 , "(number of connections to maintain in the pool.)" )
flag . IntVar ( & maxOpenConns , "max-open-conns" , 100 , "(max connections for use at any time.)" )
flag . DurationVar ( & dialTimeout , "dial-timeout" , 5 * time . Second , "(the maximum time to establish a connection.)" )
2022-10-06 20:13:30 +05:30
flag . StringVar ( & ruleRepoURL , "rules.repo-url" , baseconst . AlertHelpPage , "(host address used to build rule link in alert messages)" )
2023-09-17 10:40:45 +05:30
flag . StringVar ( & cacheConfigPath , "experimental.cache-config" , "" , "(cache config to use)" )
2024-06-25 10:10:33 +05:30
flag . StringVar ( & fluxInterval , "flux-interval" , "5m" , "(the interval to exclude data from being cached to avoid incorrect cache for data in motion)" )
2025-01-24 00:16:38 +05:30
flag . StringVar ( & fluxIntervalForTraceDetail , "flux-interval-trace-detail" , "2m" , "(the interval to exclude data from being cached to avoid incorrect cache for trace data in motion)" )
2023-06-21 11:47:30 +05:30
flag . BoolVar ( & enableQueryServiceLogOTLPExport , "enable.query.service.log.otlp.export" , false , "(enable query service log otlp export)" )
2023-10-20 12:37:45 +05:30
flag . StringVar ( & cluster , "cluster" , "cluster" , "(cluster name - defaults to 'cluster')" )
2024-06-04 18:25:24 +05:30
flag . StringVar ( & gatewayUrl , "gateway-url" , "" , "(url to the gateway)" )
2024-12-17 01:12:31 +05:30
flag . BoolVar ( & useLicensesV3 , "use-licenses-v3" , false , "use licenses_v3 schema for licenses" )
2022-10-06 20:13:30 +05:30
flag . Parse ( )
2023-06-21 11:47:30 +05:30
loggerMgr := initZapLog ( enableQueryServiceLogOTLPExport )
2023-09-17 10:40:45 +05:30
2022-10-06 20:13:30 +05:30
zap . ReplaceGlobals ( loggerMgr )
defer loggerMgr . Sync ( ) // flushes buffer, if any
version . PrintVersion ( )
2025-01-20 17:45:33 +05:30
config , err := signoz . NewConfig ( context . Background ( ) , config . ResolverConfig {
Uris : [ ] string { "env:" } ,
ProviderFactories : [ ] config . ProviderFactory {
envprovider . NewFactory ( ) ,
fileprovider . NewFactory ( ) ,
2024-12-23 16:44:48 +05:30
} ,
} )
if err != nil {
zap . L ( ) . Fatal ( "Failed to create config" , zap . Error ( err ) )
}
2025-01-20 17:45:33 +05:30
signoz , err := signoz . New ( context . Background ( ) , config , signoz . NewProviderConfig ( ) )
2025-01-04 01:28:54 +05:30
if err != nil {
zap . L ( ) . Fatal ( "Failed to create signoz struct" , zap . Error ( err ) )
2024-12-23 16:44:48 +05:30
}
2022-10-06 20:13:30 +05:30
serverOptions := & app . ServerOptions {
2025-01-24 00:16:38 +05:30
Config : config ,
SigNoz : signoz ,
HTTPHostPort : baseconst . HTTPHostPort ,
PromConfigPath : promConfigPath ,
SkipTopLvlOpsPath : skipTopLvlOpsPath ,
PreferSpanMetrics : preferSpanMetrics ,
PrivateHostPort : baseconst . PrivateHostPort ,
DisableRules : disableRules ,
RuleRepoURL : ruleRepoURL ,
MaxIdleConns : maxIdleConns ,
MaxOpenConns : maxOpenConns ,
DialTimeout : dialTimeout ,
CacheConfigPath : cacheConfigPath ,
FluxInterval : fluxInterval ,
FluxIntervalForTraceDetail : fluxIntervalForTraceDetail ,
Cluster : cluster ,
GatewayUrl : gatewayUrl ,
UseLogsNewSchema : useLogsNewSchema ,
UseTraceNewSchema : useTraceNewSchema ,
2022-10-06 20:13:30 +05:30
}
// Read the jwt secret key
auth . JwtSecret = os . Getenv ( "SIGNOZ_JWT_SECRET" )
if len ( auth . JwtSecret ) == 0 {
2024-03-27 00:07:29 +05:30
zap . L ( ) . Warn ( "No JWT secret key is specified." )
2022-10-06 20:13:30 +05:30
} else {
2024-03-27 00:07:29 +05:30
zap . L ( ) . Info ( "JWT secret key set successfully." )
2022-10-06 20:13:30 +05:30
}
2025-01-22 12:49:38 +05:30
if err := migrate . Migrate ( signoz . SQLStore . SQLxDB ( ) ) ; err != nil {
2024-05-17 07:45:03 +05:30
zap . L ( ) . Error ( "Failed to migrate" , zap . Error ( err ) )
} else {
zap . L ( ) . Info ( "Migration successful" )
}
2025-01-04 01:28:54 +05:30
server , err := app . NewServer ( serverOptions )
2022-10-06 20:13:30 +05:30
if err != nil {
2024-03-27 00:07:29 +05:30
zap . L ( ) . Fatal ( "Failed to create server" , zap . Error ( err ) )
2022-10-06 20:13:30 +05:30
}
if err := server . Start ( ) ; err != nil {
2024-03-27 00:07:29 +05:30
zap . L ( ) . Fatal ( "Could not start server" , zap . Error ( err ) )
2022-10-06 20:13:30 +05:30
}
if err := auth . InitAuthCache ( context . Background ( ) ) ; err != nil {
2024-03-27 00:07:29 +05:30
zap . L ( ) . Fatal ( "Failed to initialize auth cache" , zap . Error ( err ) )
2022-10-06 20:13:30 +05:30
}
signalsChannel := make ( chan os . Signal , 1 )
signal . Notify ( signalsChannel , os . Interrupt , syscall . SIGTERM )
for {
select {
case status := <- server . HealthCheckStatus ( ) :
2024-03-27 00:07:29 +05:30
zap . L ( ) . Info ( "Received HealthCheck status: " , zap . Int ( "status" , int ( status ) ) )
2022-10-06 20:13:30 +05:30
case <- signalsChannel :
2024-03-27 00:07:29 +05:30
zap . L ( ) . Fatal ( "Received OS Interrupt Signal ... " )
2023-08-01 10:19:56 +05:30
server . Stop ( )
2022-10-06 20:13:30 +05:30
}
}
}