2019-05-22 21:16:55 +00:00
package main
import (
"flag"
2020-10-06 11:54:39 +00:00
"fmt"
2019-05-22 21:16:55 +00:00
"net/http"
2020-05-16 08:59:30 +00:00
"os"
2019-05-22 21:16:55 +00:00
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert"
2023-04-01 04:27:45 +00:00
vminsertcommon "github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert/common"
vminsertrelabel "github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert/relabel"
2019-05-22 21:16:55 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect"
2020-12-14 11:08:22 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/promql"
2019-05-22 21:16:55 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
2020-02-10 11:26:18 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/envflag"
2020-12-25 14:40:20 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
2019-11-12 14:18:09 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
2019-05-22 21:16:55 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/procutil"
2020-11-25 20:59:13 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape"
2022-07-21 16:58:22 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/pushmetrics"
2020-02-10 11:03:52 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
2019-05-22 21:16:55 +00:00
)
2020-02-10 11:03:52 +00:00
var (
2024-02-09 01:15:04 +00:00
httpListenAddrs = flagutil . NewArrayString ( "httpListenAddr" , "TCP addresses to listen for incoming http requests. See also -tls and -httpListenAddr.useProxyProtocol" )
useProxyProtocol = flagutil . NewArrayBool ( "httpListenAddr.useProxyProtocol" , "Whether to use proxy protocol for connections accepted at the corresponding -httpListenAddr . " +
2023-03-08 09:26:53 +00:00
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . " +
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing" )
2022-05-02 18:35:14 +00:00
minScrapeInterval = flag . Duration ( "dedup.minScrapeInterval" , 0 , "Leave only the last sample in every time series per each discrete interval " +
2024-03-04 22:45:22 +00:00
"equal to -dedup.minScrapeInterval > 0. See also -streamAggr.dedupInterval and https://docs.victoriametrics.com/#deduplication" )
2023-04-01 04:27:45 +00:00
dryRun = flag . Bool ( "dryRun" , false , "Whether to check config files without running VictoriaMetrics. The following config files are checked: " +
"-promscrape.config, -relabelConfig and -streamAggr.config. Unknown config entries aren't allowed in -promscrape.config by default. " +
"This can be changed with -promscrape.config.strictParse=false command-line flag" )
2022-12-05 23:15:00 +00:00
inmemoryDataFlushInterval = flag . Duration ( "inmemoryDataFlushInterval" , 5 * time . Second , "The interval for guaranteed saving of in-memory data to disk. " +
2023-07-19 08:10:51 +00:00
"The saved data survives unclean shutdowns such as OOM crash, hardware reset, SIGKILL, etc. " +
"Bigger intervals may help increase the lifetime of flash storage with limited write cycles (e.g. Raspberry PI). " +
2022-12-05 23:15:00 +00:00
"Smaller intervals increase disk IO load. Minimum supported value is 1s" )
2022-10-06 22:16:52 +00:00
downsamplingPeriods = flagutil . NewArrayString ( "downsampling.period" , "Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs " +
2021-12-15 14:23:27 +00:00
"to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details" )
2020-02-10 11:03:52 +00:00
)
2019-05-22 21:16:55 +00:00
2020-12-15 12:20:51 +00:00
// custom api help links [["/api","doc"]] without http.pathPrefix.
var customAPIPathList = [ ] [ ] string {
{ "/graph/explore" , "explore metrics grafana page" } ,
{ "/graph/d/prometheus-advanced/advanced-data-exploration" , "PMM grafana dashboard" } ,
}
2019-05-22 21:16:55 +00:00
func main ( ) {
2020-05-16 08:59:30 +00:00
// Write flags and help message to stdout, since it is easier to grep or pipe.
flag . CommandLine . SetOutput ( os . Stdout )
2020-12-25 14:40:20 +00:00
flag . Usage = usage
2020-02-10 11:26:18 +00:00
envflag . Parse ( )
2019-05-22 21:16:55 +00:00
buildinfo . Init ( )
logger . Init ( )
2020-11-25 20:59:13 +00:00
if promscrape . IsDryRun ( ) {
* dryRun = true
}
if * dryRun {
if err := promscrape . CheckConfig ( ) ; err != nil {
logger . Fatalf ( "error when checking -promscrape.config: %s" , err )
}
2023-04-01 04:27:45 +00:00
if err := vminsertrelabel . CheckRelabelConfig ( ) ; err != nil {
logger . Fatalf ( "error when checking -relabelConfig: %s" , err )
}
if err := vminsertcommon . CheckStreamAggrConfig ( ) ; err != nil {
logger . Fatalf ( "error when checking -streamAggr.config: %s" , err )
}
2023-03-03 10:02:13 +00:00
logger . Infof ( "-promscrape.config is ok; exiting with 0 status code" )
2020-11-25 20:59:13 +00:00
return
}
2024-02-09 01:15:04 +00:00
listenAddrs := * httpListenAddrs
if len ( listenAddrs ) == 0 {
listenAddrs = [ ] string { ":8428" }
}
logger . Infof ( "starting VictoriaMetrics at %q..." , listenAddrs )
2019-05-22 21:16:55 +00:00
startTime := time . Now ( )
2021-12-15 14:23:27 +00:00
err := storage . SetDownsamplingPeriods ( * downsamplingPeriods , * minScrapeInterval )
if err != nil {
logger . Fatalf ( "cannot parse -downsampling.period: %s" , err )
}
2022-12-05 23:15:00 +00:00
storage . SetDataFlushInterval ( * inmemoryDataFlushInterval )
2020-12-14 11:08:22 +00:00
vmstorage . Init ( promql . ResetRollupResultCacheIfNeeded )
2019-05-22 21:16:55 +00:00
vmselect . Init ( )
vminsert . Init ( )
2024-01-15 11:37:02 +00:00
2020-01-25 17:19:23 +00:00
startSelfScraper ( )
2019-05-22 21:16:55 +00:00
2024-02-09 01:15:04 +00:00
go httpserver . Serve ( listenAddrs , useProxyProtocol , requestHandler )
2020-01-22 16:27:44 +00:00
logger . Infof ( "started VictoriaMetrics in %.3f seconds" , time . Since ( startTime ) . Seconds ( ) )
2019-05-22 21:16:55 +00:00
2024-01-15 11:37:02 +00:00
pushmetrics . Init ( )
2019-05-22 21:16:55 +00:00
sig := procutil . WaitForSigterm ( )
logger . Infof ( "received signal %s" , sig )
2024-01-15 11:37:02 +00:00
pushmetrics . Stop ( )
2019-05-22 21:16:55 +00:00
2020-01-25 17:19:23 +00:00
stopSelfScraper ( )
2024-02-09 01:15:04 +00:00
logger . Infof ( "gracefully shutting down webservice at %q" , listenAddrs )
2019-05-22 21:16:55 +00:00
startTime = time . Now ( )
2024-02-09 01:15:04 +00:00
if err := httpserver . Stop ( listenAddrs ) ; err != nil {
2019-05-22 21:16:55 +00:00
logger . Fatalf ( "cannot stop the webservice: %s" , err )
}
2020-01-22 16:27:44 +00:00
logger . Infof ( "successfully shut down the webservice in %.3f seconds" , time . Since ( startTime ) . Seconds ( ) )
2024-01-15 11:37:02 +00:00
vminsert . Stop ( )
2019-05-22 21:16:55 +00:00
vmstorage . Stop ( )
vmselect . Stop ( )
2019-11-12 14:18:09 +00:00
fs . MustStopDirRemover ( )
2020-01-22 16:27:44 +00:00
logger . Infof ( "the VictoriaMetrics has been stopped in %.3f seconds" , time . Since ( startTime ) . Seconds ( ) )
2019-05-22 21:16:55 +00:00
}
func requestHandler ( w http . ResponseWriter , r * http . Request ) bool {
2020-12-14 11:36:48 +00:00
if r . URL . Path == "/" {
2023-02-23 02:58:44 +00:00
if r . Method != http . MethodGet {
2021-04-02 19:54:06 +00:00
return false
}
2022-03-21 08:13:28 +00:00
w . Header ( ) . Add ( "Content-Type" , "text/html; charset=utf-8" )
2021-04-30 06:19:08 +00:00
fmt . Fprintf ( w , "<h2>Single-node VictoriaMetrics</h2></br>" )
2021-04-20 17:16:17 +00:00
fmt . Fprintf ( w , "See docs at <a href='https://docs.victoriametrics.com/'>https://docs.victoriametrics.com/</a></br>" )
2021-04-30 06:19:08 +00:00
fmt . Fprintf ( w , "Useful endpoints:</br>" )
httpserver . WriteAPIHelp ( w , [ ] [ 2 ] string {
2021-12-02 11:51:49 +00:00
{ "vmui" , "Web UI" } ,
2022-06-06 21:57:05 +00:00
{ "targets" , "status for discovered active targets" } ,
{ "service-discovery" , "labels before and after relabeling for discovered targets" } ,
2022-12-10 10:09:21 +00:00
{ "metric-relabel-debug" , "debug metric relabeling" } ,
2022-12-15 00:01:33 +00:00
{ "expand-with-exprs" , "WITH expressions' tutorial" } ,
2021-12-02 11:51:49 +00:00
{ "api/v1/targets" , "advanced information about discovered targets in JSON format" } ,
{ "config" , "-promscrape.config contents" } ,
{ "metrics" , "available service metrics" } ,
{ "flags" , "command-line flags" } ,
{ "api/v1/status/tsdb" , "tsdb status page" } ,
{ "api/v1/status/top_queries" , "top queries" } ,
{ "api/v1/status/active_queries" , "active queries" } ,
2024-02-07 20:05:02 +00:00
{ "-/reload" , "reload configuration" } ,
2020-12-14 11:36:48 +00:00
} )
2021-04-30 07:11:24 +00:00
for _ , p := range customAPIPathList {
p , doc := p [ 0 ] , p [ 1 ]
fmt . Fprintf ( w , "<a href=%q>%s</a> - %s<br/>" , p , p , doc )
}
2020-10-06 11:54:39 +00:00
return true
}
2019-05-22 21:16:55 +00:00
if vminsert . RequestHandler ( w , r ) {
return true
}
if vmselect . RequestHandler ( w , r ) {
return true
}
if vmstorage . RequestHandler ( w , r ) {
return true
}
return false
}
2020-12-14 11:36:48 +00:00
2020-12-25 14:40:20 +00:00
func usage ( ) {
const s = `
victoria - metrics is a time series database and monitoring solution .
2021-04-20 17:16:17 +00:00
See the docs at https : //docs.victoriametrics.com/
2020-12-25 14:40:20 +00:00
`
flagutil . Usage ( s )
}