2019-05-22 23:23:23 +02:00
package main
2019-05-22 23:16:55 +02:00
import (
"flag"
"fmt"
"net/http"
2020-05-16 10:59:30 +02:00
"os"
2019-05-22 23:16:55 +02:00
"strings"
"sync"
"time"
2019-05-22 23:23:23 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage/transport"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
2020-02-10 12:26:18 +01:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/envflag"
2020-10-20 13:29:26 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
2019-11-12 15:29:43 +01:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
2019-05-22 23:16:55 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
2019-05-22 23:23:23 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/procutil"
2021-05-08 16:55:44 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/common"
2019-05-22 23:16:55 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
"github.com/VictoriaMetrics/metrics"
)
var (
2020-10-20 13:29:26 +02:00
retentionPeriod = flagutil . NewDuration ( "retentionPeriod" , 1 , "Data with timestamps outside the retentionPeriod is automatically deleted" )
2020-09-17 13:21:39 +02:00
httpListenAddr = flag . String ( "httpListenAddr" , ":8482" , "Address to listen for http connections" )
storageDataPath = flag . String ( "storageDataPath" , "vmstorage-data" , "Path to storage data" )
vminsertAddr = flag . String ( "vminsertAddr" , ":8400" , "TCP address to accept connections from vminsert services" )
vmselectAddr = flag . String ( "vmselectAddr" , ":8401" , "TCP address to accept connections from vmselect services" )
snapshotAuthKey = flag . String ( "snapshotAuthKey" , "" , "authKey, which must be passed in query string to /snapshot* pages" )
forceMergeAuthKey = flag . String ( "forceMergeAuthKey" , "" , "authKey, which must be passed in query string to /internal/force_merge pages" )
2020-11-11 13:40:27 +01:00
forceFlushAuthKey = flag . String ( "forceFlushAuthKey" , "" , "authKey, which must be passed in query string to /internal/force_flush pages" )
2019-10-31 15:16:53 +01:00
2021-01-07 23:09:00 +01:00
finalMergeDelay = flag . Duration ( "finalMergeDelay" , 0 , "The delay before starting final merge for per-month partition after no new data is ingested into it. " +
"Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. " +
"Zero value disables final merge" )
2019-10-31 15:16:53 +01:00
bigMergeConcurrency = flag . Int ( "bigMergeConcurrency" , 0 , "The maximum number of CPU cores to use for big merges. Default value is used if set to 0" )
smallMergeConcurrency = flag . Int ( "smallMergeConcurrency" , 0 , "The maximum number of CPU cores to use for small merges. Default value is used if set to 0" )
2020-02-10 12:03:52 +01:00
minScrapeInterval = flag . Duration ( "dedup.minScrapeInterval" , 0 , "Remove superflouos samples from time series if they are located closer to each other than this duration. " +
"This may be useful for reducing overhead when multiple identically configured Prometheus instances write data to the same VictoriaMetrics. " +
"Deduplication is disabled if the -dedup.minScrapeInterval is 0" )
2021-03-15 21:38:50 +01:00
logNewSeries = flag . Bool ( "logNewSeries" , false , "Whether to log new series. This option is for debug purposes only. It can lead to performance issues " +
"when big number of new series are ingested into VictoriaMetrics" )
2021-05-20 13:15:19 +02:00
maxHourlySeries = flag . Int ( "storage.maxHourlySeries" , 0 , "The maximum number of unique series can be added to the storage during the last hour. " +
"Excess series are logged and dropped. This can be useful for limiting series cardinality. See also -storage.maxDailySeries" )
maxDailySeries = flag . Int ( "storage.maxDailySeries" , 0 , "The maximum number of unique series can be added to the storage during the last 24 hours. " +
"Excess series are logged and dropped. This can be useful for limiting series churn rate. See also -storage.maxHourlySeries" )
2019-05-22 23:16:55 +02:00
)
2019-05-22 23:23:23 +02:00
func main ( ) {
2020-05-16 10:59:30 +02:00
// Write flags and help message to stdout, since it is easier to grep or pipe.
flag . CommandLine . SetOutput ( os . Stdout )
2020-12-03 20:40:30 +01:00
flag . Usage = usage
2020-02-10 12:26:18 +01:00
envflag . Parse ( )
2019-05-22 23:23:23 +02:00
buildinfo . Init ( )
logger . Init ( )
2020-02-10 12:03:52 +01:00
storage . SetMinScrapeIntervalForDeduplication ( * minScrapeInterval )
2021-03-15 21:38:50 +01:00
storage . SetLogNewSeries ( * logNewSeries )
2020-10-07 16:35:42 +02:00
storage . SetFinalMergeDelay ( * finalMergeDelay )
2019-10-31 15:16:53 +01:00
storage . SetBigMergeWorkersCount ( * bigMergeConcurrency )
storage . SetSmallMergeWorkersCount ( * smallMergeConcurrency )
2020-10-20 13:29:26 +02:00
logger . Infof ( "opening storage at %q with -retentionPeriod=%s" , * storageDataPath , retentionPeriod )
2019-05-22 23:16:55 +02:00
startTime := time . Now ( )
2021-05-20 13:15:19 +02:00
strg , err := storage . OpenStorage ( * storageDataPath , retentionPeriod . Msecs , * maxHourlySeries , * maxDailySeries )
2019-05-22 23:16:55 +02:00
if err != nil {
2020-10-20 13:29:26 +02:00
logger . Fatalf ( "cannot open a storage at %s with -retentionPeriod=%s: %s" , * storageDataPath , retentionPeriod , err )
2019-05-22 23:16:55 +02:00
}
var m storage . Metrics
2019-05-22 23:23:23 +02:00
strg . UpdateMetrics ( & m )
2019-05-22 23:16:55 +02:00
tm := & m . TableMetrics
partsCount := tm . SmallPartsCount + tm . BigPartsCount
blocksCount := tm . SmallBlocksCount + tm . BigBlocksCount
rowsCount := tm . SmallRowsCount + tm . BigRowsCount
2019-07-04 18:09:40 +02:00
sizeBytes := tm . SmallSizeBytes + tm . BigSizeBytes
2020-01-22 17:27:44 +01:00
logger . Infof ( "successfully opened storage %q in %.3f seconds; partsCount: %d; blocksCount: %d; rowsCount: %d; sizeBytes: %d" ,
* storageDataPath , time . Since ( startTime ) . Seconds ( ) , partsCount , blocksCount , rowsCount , sizeBytes )
2019-05-22 23:16:55 +02:00
2019-05-22 23:23:23 +02:00
registerStorageMetrics ( strg )
2019-05-22 23:16:55 +02:00
2021-05-08 16:55:44 +02:00
common . StartUnmarshalWorkers ( )
2019-05-22 23:23:23 +02:00
srv , err := transport . NewServer ( * vminsertAddr , * vmselectAddr , strg )
if err != nil {
logger . Fatalf ( "cannot create a server with vminsertAddr=%s, vmselectAddr=%s: %s" , * vminsertAddr , * vmselectAddr , err )
}
2019-05-22 23:16:55 +02:00
2019-05-22 23:23:23 +02:00
go srv . RunVMInsert ( )
go srv . RunVMSelect ( )
2019-05-22 23:16:55 +02:00
2019-05-22 23:23:23 +02:00
requestHandler := newRequestHandler ( strg )
go func ( ) {
httpserver . Serve ( * httpListenAddr , requestHandler )
} ( )
2019-05-22 23:16:55 +02:00
2019-05-22 23:23:23 +02:00
sig := procutil . WaitForSigterm ( )
logger . Infof ( "service received signal %s" , sig )
2019-05-22 23:16:55 +02:00
app/vmstorage: add missing shutdown for http server on graceful shutdown
This could result in the following panic during graceful shutdown when `/metrics` page is requested:
http: panic serving 10.101.66.5:57366: runtime error: invalid memory address or nil pointer dereference
goroutine 2050 [running]:
net/http.(*conn).serve.func1(0xc00ef22000)
net/http/server.go:1772 +0x139
panic(0xa0fc00, 0xe91d80)
runtime/panic.go:973 +0x3e3
github.com/VictoriaMetrics/VictoriaMetrics/lib/workingsetcache.(*Cache).UpdateStats(0x0, 0xc0000516c8)
github.com/VictoriaMetrics/VictoriaMetrics/lib/workingsetcache/cache.go:224 +0x37
github.com/VictoriaMetrics/VictoriaMetrics/lib/storage.(*indexDB).UpdateMetrics(0xc00b931d00, 0xc02c41acf8)
github.com/VictoriaMetrics/VictoriaMetrics/lib/storage/index_db.go:258 +0x9f
github.com/VictoriaMetrics/VictoriaMetrics/lib/storage.(*Storage).UpdateMetrics(0xc0000bc7e0, 0xc02c41ac00)
github.com/VictoriaMetrics/VictoriaMetrics/lib/storage/storage.go:413 +0x4c5
main.registerStorageMetrics.func1(0x0)
github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage/main.go:186 +0xd9
main.registerStorageMetrics.func3(0xc00008c380)
github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage/main.go:196 +0x26
main.registerStorageMetrics.func7(0xc)
github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage/main.go:211 +0x26
github.com/VictoriaMetrics/metrics.(*Gauge).marshalTo(0xc000010148, 0xaa407d, 0x20, 0xb50d60, 0xc005319890)
github.com/VictoriaMetrics/metrics@v1.11.2/gauge.go:38 +0x3f
github.com/VictoriaMetrics/metrics.(*Set).WritePrometheus(0xc000084300, 0x7fd56809c940, 0xc005319860)
github.com/VictoriaMetrics/metrics@v1.11.2/set.go:51 +0x1e1
github.com/VictoriaMetrics/metrics.WritePrometheus(0x7fd56809c940, 0xc005319860, 0xa16f01)
github.com/VictoriaMetrics/metrics@v1.11.2/metrics.go:42 +0x41
github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver.writePrometheusMetrics(0x7fd56809c940, 0xc005319860)
github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver/metrics.go:16 +0x44
github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver.handlerWrapper(0xb5a120, 0xc005319860, 0xc005018f00, 0xc00002cc90)
github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver/httpserver.go:154 +0x58d
github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver.gzipHandler.func1(0xb5a120, 0xc005319860, 0xc005018f00)
github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver/httpserver.go:119 +0x8e
net/http.HandlerFunc.ServeHTTP(0xc00002d110, 0xb5a660, 0xc0044141c0, 0xc005018f00)
net/http/server.go:2012 +0x44
net/http.serverHandler.ServeHTTP(0xc004414000, 0xb5a660, 0xc0044141c0, 0xc005018f00)
net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc00ef22000, 0xb5bf60, 0xc010532080)
net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
net/http/server.go:2933 +0x35c
2020-04-02 20:07:59 +02:00
logger . Infof ( "gracefully shutting down http service at %q" , * httpListenAddr )
startTime = time . Now ( )
if err := httpserver . Stop ( * httpListenAddr ) ; err != nil {
logger . Fatalf ( "cannot stop http service: %s" , err )
}
logger . Infof ( "successfully shut down http service in %.3f seconds" , time . Since ( startTime ) . Seconds ( ) )
2019-05-22 23:23:23 +02:00
logger . Infof ( "gracefully shutting down the service" )
startTime = time . Now ( )
srv . MustClose ( )
2021-05-08 16:55:44 +02:00
common . StopUnmarshalWorkers ( )
2020-01-22 17:27:44 +01:00
logger . Infof ( "successfully shut down the service in %.3f seconds" , time . Since ( startTime ) . Seconds ( ) )
2019-05-22 23:16:55 +02:00
2019-05-22 23:23:23 +02:00
logger . Infof ( "gracefully closing the storage at %s" , * storageDataPath )
startTime = time . Now ( )
strg . MustClose ( )
2020-01-22 17:27:44 +01:00
logger . Infof ( "successfully closed the storage in %.3f seconds" , time . Since ( startTime ) . Seconds ( ) )
2019-05-22 23:16:55 +02:00
2019-11-12 15:29:43 +01:00
fs . MustStopDirRemover ( )
2019-05-22 23:23:23 +02:00
logger . Infof ( "the vmstorage has been stopped" )
2019-05-22 23:16:55 +02:00
}
2019-05-22 23:23:23 +02:00
func newRequestHandler ( strg * storage . Storage ) httpserver . RequestHandler {
return func ( w http . ResponseWriter , r * http . Request ) bool {
2020-12-14 13:02:57 +01:00
if r . URL . Path == "/" {
2021-04-02 21:54:06 +02:00
if r . Method != "GET" {
return false
}
2021-04-20 19:16:17 +02:00
fmt . Fprintf ( w , "vmstorage - a component of VictoriaMetrics cluster. See docs at https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html" )
2020-10-06 14:00:38 +02:00
return true
}
2019-05-22 23:23:23 +02:00
return requestHandler ( w , r , strg )
2019-05-22 23:16:55 +02:00
}
2019-05-22 23:23:23 +02:00
}
func requestHandler ( w http . ResponseWriter , r * http . Request , strg * storage . Storage ) bool {
path := r . URL . Path
2020-09-17 11:01:53 +02:00
if path == "/internal/force_merge" {
2020-09-17 13:21:39 +02:00
authKey := r . FormValue ( "authKey" )
if authKey != * forceMergeAuthKey {
httpserver . Errorf ( w , r , "invalid authKey %q. It must match the value from -forceMergeAuthKey command line flag" , authKey )
return true
}
2020-09-17 11:01:53 +02:00
// Run force merge in background
partitionNamePrefix := r . FormValue ( "partition_prefix" )
go func ( ) {
activeForceMerges . Inc ( )
defer activeForceMerges . Dec ( )
logger . Infof ( "forced merge for partition_prefix=%q has been started" , partitionNamePrefix )
startTime := time . Now ( )
if err := strg . ForceMergePartitions ( partitionNamePrefix ) ; err != nil {
logger . Errorf ( "error in forced merge for partition_prefix=%q: %s" , partitionNamePrefix , err )
return
}
logger . Infof ( "forced merge for partition_prefix=%q has been successfully finished in %.3f seconds" , partitionNamePrefix , time . Since ( startTime ) . Seconds ( ) )
} ( )
return true
}
2020-11-11 13:40:27 +01:00
if path == "/internal/force_flush" {
authKey := r . FormValue ( "authKey" )
if authKey != * forceFlushAuthKey {
httpserver . Errorf ( w , r , "invalid authKey %q. It must match the value from -forceFlushAuthKey command line flag" , authKey )
return true
}
logger . Infof ( "flushing storage to make pending data available for reading" )
strg . DebugFlush ( )
return true
}
2019-05-22 23:16:55 +02:00
if ! strings . HasPrefix ( path , "/snapshot" ) {
return false
}
authKey := r . FormValue ( "authKey" )
if authKey != * snapshotAuthKey {
2020-07-20 13:00:33 +02:00
httpserver . Errorf ( w , r , "invalid authKey %q. It must match the value from -snapshotAuthKey command line flag" , authKey )
2019-05-22 23:16:55 +02:00
return true
}
path = path [ len ( "/snapshot" ) : ]
switch path {
case "/create" :
2020-11-13 09:25:39 +01:00
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=utf-8" )
2019-05-22 23:23:23 +02:00
snapshotPath , err := strg . CreateSnapshot ( )
2019-05-22 23:16:55 +02:00
if err != nil {
2020-06-30 21:58:18 +02:00
err = fmt . Errorf ( "cannot create snapshot: %w" , err )
2020-03-10 22:51:50 +01:00
jsonResponseError ( w , err )
2019-05-22 23:16:55 +02:00
return true
}
2019-05-22 23:23:23 +02:00
fmt . Fprintf ( w , ` { "status":"ok","snapshot":%q} ` , snapshotPath )
2019-05-22 23:16:55 +02:00
return true
case "/list" :
2020-11-13 09:25:39 +01:00
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=utf-8" )
2019-05-22 23:23:23 +02:00
snapshots , err := strg . ListSnapshots ( )
2019-05-22 23:16:55 +02:00
if err != nil {
2020-06-30 21:58:18 +02:00
err = fmt . Errorf ( "cannot list snapshots: %w" , err )
2020-03-10 22:51:50 +01:00
jsonResponseError ( w , err )
2019-05-22 23:16:55 +02:00
return true
}
fmt . Fprintf ( w , ` { "status":"ok","snapshots":[ ` )
if len ( snapshots ) > 0 {
for _ , snapshot := range snapshots [ : len ( snapshots ) - 1 ] {
fmt . Fprintf ( w , "\n%q," , snapshot )
}
fmt . Fprintf ( w , "\n%q\n" , snapshots [ len ( snapshots ) - 1 ] )
}
fmt . Fprintf ( w , ` ]} ` )
return true
case "/delete" :
2020-11-13 09:25:39 +01:00
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=utf-8" )
2019-05-22 23:16:55 +02:00
snapshotName := r . FormValue ( "snapshot" )
2019-05-22 23:23:23 +02:00
if err := strg . DeleteSnapshot ( snapshotName ) ; err != nil {
2020-06-30 21:58:18 +02:00
err = fmt . Errorf ( "cannot delete snapshot %q: %w" , snapshotName , err )
2020-03-10 22:51:50 +01:00
jsonResponseError ( w , err )
2019-05-22 23:16:55 +02:00
return true
}
fmt . Fprintf ( w , ` { "status":"ok"} ` )
return true
case "/delete_all" :
2020-11-13 09:25:39 +01:00
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=utf-8" )
2019-05-22 23:23:23 +02:00
snapshots , err := strg . ListSnapshots ( )
2019-05-22 23:16:55 +02:00
if err != nil {
2020-06-30 21:58:18 +02:00
err = fmt . Errorf ( "cannot list snapshots: %w" , err )
2020-03-10 22:51:50 +01:00
jsonResponseError ( w , err )
2019-05-22 23:16:55 +02:00
return true
}
for _ , snapshotName := range snapshots {
2019-05-22 23:23:23 +02:00
if err := strg . DeleteSnapshot ( snapshotName ) ; err != nil {
2020-06-30 21:58:18 +02:00
err = fmt . Errorf ( "cannot delete snapshot %q: %w" , snapshotName , err )
2020-03-10 22:51:50 +01:00
jsonResponseError ( w , err )
2019-05-22 23:16:55 +02:00
return true
}
}
fmt . Fprintf ( w , ` { "status":"ok"} ` )
return true
default :
return false
}
}
2020-09-17 11:01:53 +02:00
var activeForceMerges = metrics . NewCounter ( "vm_active_force_merges" )
2019-05-22 23:16:55 +02:00
func registerStorageMetrics ( strg * storage . Storage ) {
mCache := & storage . Metrics { }
var mCacheLock sync . Mutex
var lastUpdateTime time . Time
m := func ( ) * storage . Metrics {
mCacheLock . Lock ( )
defer mCacheLock . Unlock ( )
if time . Since ( lastUpdateTime ) < time . Second {
return mCache
}
var mc storage . Metrics
strg . UpdateMetrics ( & mc )
mCache = & mc
lastUpdateTime = time . Now ( )
return mCache
}
tm := func ( ) * storage . TableMetrics {
sm := m ( )
return & sm . TableMetrics
}
idbm := func ( ) * storage . IndexDBMetrics {
sm := m ( )
return & sm . IndexDBMetrics
}
2020-04-01 22:43:09 +02:00
metrics . NewGauge ( fmt . Sprintf ( ` vm_free_disk_space_bytes { path=%q} ` , * storageDataPath ) , func ( ) float64 {
return float64 ( fs . MustGetFreeSpace ( * storageDataPath ) )
2020-04-01 22:08:58 +02:00
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_active_merges { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . ActiveBigMerges )
} )
metrics . NewGauge ( ` vm_active_merges { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . ActiveSmallMerges )
} )
metrics . NewGauge ( ` vm_active_merges { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . ActiveMerges )
} )
metrics . NewGauge ( ` vm_merges_total { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigMergesCount )
} )
metrics . NewGauge ( ` vm_merges_total { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallMergesCount )
} )
metrics . NewGauge ( ` vm_merges_total { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . MergesCount )
} )
metrics . NewGauge ( ` vm_rows_merged_total { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigRowsMerged )
} )
metrics . NewGauge ( ` vm_rows_merged_total { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallRowsMerged )
} )
metrics . NewGauge ( ` vm_rows_merged_total { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . ItemsMerged )
} )
metrics . NewGauge ( ` vm_rows_deleted_total { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigRowsDeleted )
} )
metrics . NewGauge ( ` vm_rows_deleted_total { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallRowsDeleted )
} )
metrics . NewGauge ( ` vm_references { type="storage/big", name="parts"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigPartsRefCount )
} )
metrics . NewGauge ( ` vm_references { type="storage/small", name="parts"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallPartsRefCount )
} )
metrics . NewGauge ( ` vm_references { type="storage", name="partitions"} ` , func ( ) float64 {
return float64 ( tm ( ) . PartitionsRefCount )
} )
metrics . NewGauge ( ` vm_references { type="indexdb", name="objects"} ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexDBRefCount )
} )
metrics . NewGauge ( ` vm_references { type="indexdb", name="parts"} ` , func ( ) float64 {
return float64 ( idbm ( ) . PartsRefCount )
} )
2019-11-08 18:57:57 +01:00
metrics . NewGauge ( ` vm_new_timeseries_created_total ` , func ( ) float64 {
return float64 ( idbm ( ) . NewTimeseriesCreated )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_missing_tsids_for_metric_id_total ` , func ( ) float64 {
return float64 ( idbm ( ) . MissingTSIDsForMetricID )
} )
2019-06-09 21:11:09 +02:00
metrics . NewGauge ( ` vm_date_metric_ids_search_calls_total ` , func ( ) float64 {
2019-06-09 18:06:53 +02:00
return float64 ( idbm ( ) . DateMetricIDsSearchCalls )
} )
2019-06-09 21:11:09 +02:00
metrics . NewGauge ( ` vm_date_metric_ids_search_hits_total ` , func ( ) float64 {
2019-06-09 18:06:53 +02:00
return float64 ( idbm ( ) . DateMetricIDsSearchHits )
} )
2019-11-06 13:24:48 +01:00
metrics . NewGauge ( ` vm_index_blocks_with_metric_ids_processed_total ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexBlocksWithMetricIDsProcessed )
} )
metrics . NewGauge ( ` vm_index_blocks_with_metric_ids_incorrect_order_total ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexBlocksWithMetricIDsIncorrectOrder )
} )
2021-02-10 15:53:26 +01:00
metrics . NewGauge ( ` vm_composite_index_min_timestamp ` , func ( ) float64 {
return float64 ( idbm ( ) . MinTimestampForCompositeIndex ) / 1e3
} )
2021-02-17 18:13:38 +01:00
metrics . NewGauge ( ` vm_composite_filter_success_conversions_total ` , func ( ) float64 {
return float64 ( idbm ( ) . CompositeFilterSuccessConversions )
} )
metrics . NewGauge ( ` vm_composite_filter_missing_conversions_total ` , func ( ) float64 {
return float64 ( idbm ( ) . CompositeFilterMissingConversions )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_assisted_merges_total { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallAssistedMerges )
} )
metrics . NewGauge ( ` vm_assisted_merges_total { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . AssistedMerges )
} )
2020-09-29 20:47:40 +02:00
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/686
2020-09-29 21:44:16 +02:00
metrics . NewGauge ( ` vm_merge_need_free_disk_space { type="storage/small"} ` , func ( ) float64 {
2020-09-29 20:47:40 +02:00
return float64 ( tm ( ) . SmallMergeNeedFreeDiskSpace )
} )
2020-09-29 21:44:16 +02:00
metrics . NewGauge ( ` vm_merge_need_free_disk_space { type="storage/big"} ` , func ( ) float64 {
2020-09-29 20:47:40 +02:00
return float64 ( tm ( ) . BigMergeNeedFreeDiskSpace )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_pending_rows { type="storage"} ` , func ( ) float64 {
return float64 ( tm ( ) . PendingRows )
} )
metrics . NewGauge ( ` vm_pending_rows { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . PendingItems )
} )
metrics . NewGauge ( ` vm_parts { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigPartsCount )
} )
metrics . NewGauge ( ` vm_parts { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallPartsCount )
} )
metrics . NewGauge ( ` vm_parts { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . PartsCount )
} )
metrics . NewGauge ( ` vm_blocks { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigBlocksCount )
} )
metrics . NewGauge ( ` vm_blocks { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallBlocksCount )
} )
metrics . NewGauge ( ` vm_blocks { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . BlocksCount )
} )
2019-07-04 18:09:40 +02:00
metrics . NewGauge ( ` vm_data_size_bytes { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigSizeBytes )
} )
metrics . NewGauge ( ` vm_data_size_bytes { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallSizeBytes )
} )
metrics . NewGauge ( ` vm_data_size_bytes { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . SizeBytes )
} )
2020-10-09 12:35:48 +02:00
metrics . NewGauge ( ` vm_rows_added_to_storage_total ` , func ( ) float64 {
return float64 ( m ( ) . RowsAddedTotal )
} )
2020-02-27 22:47:05 +01:00
metrics . NewGauge ( ` vm_deduplicated_samples_total { type="merge"} ` , func ( ) float64 {
return float64 ( m ( ) . DedupsDuringMerge )
} )
2019-07-26 19:00:35 +02:00
metrics . NewGauge ( ` vm_rows_ignored_total { reason="big_timestamp"} ` , func ( ) float64 {
2019-07-26 13:10:25 +02:00
return float64 ( m ( ) . TooBigTimestampRows )
} )
2019-07-26 19:00:35 +02:00
metrics . NewGauge ( ` vm_rows_ignored_total { reason="small_timestamp"} ` , func ( ) float64 {
2019-07-26 13:10:25 +02:00
return float64 ( m ( ) . TooSmallTimestampRows )
} )
2019-08-06 13:09:17 +02:00
metrics . NewGauge ( ` vm_concurrent_addrows_limit_reached_total ` , func ( ) float64 {
return float64 ( m ( ) . AddRowsConcurrencyLimitReached )
} )
metrics . NewGauge ( ` vm_concurrent_addrows_limit_timeout_total ` , func ( ) float64 {
return float64 ( m ( ) . AddRowsConcurrencyLimitTimeout )
} )
metrics . NewGauge ( ` vm_concurrent_addrows_dropped_rows_total ` , func ( ) float64 {
return float64 ( m ( ) . AddRowsConcurrencyDroppedRows )
} )
metrics . NewGauge ( ` vm_concurrent_addrows_capacity ` , func ( ) float64 {
return float64 ( m ( ) . AddRowsConcurrencyCapacity )
} )
metrics . NewGauge ( ` vm_concurrent_addrows_current ` , func ( ) float64 {
return float64 ( m ( ) . AddRowsConcurrencyCurrent )
} )
2020-08-05 17:24:51 +02:00
metrics . NewGauge ( ` vm_concurrent_search_tsids_limit_reached_total ` , func ( ) float64 {
return float64 ( m ( ) . SearchTSIDsConcurrencyLimitReached )
} )
metrics . NewGauge ( ` vm_concurrent_search_tsids_limit_timeout_total ` , func ( ) float64 {
return float64 ( m ( ) . SearchTSIDsConcurrencyLimitTimeout )
} )
metrics . NewGauge ( ` vm_concurrent_search_tsids_capacity ` , func ( ) float64 {
return float64 ( m ( ) . SearchTSIDsConcurrencyCapacity )
} )
metrics . NewGauge ( ` vm_concurrent_search_tsids_current ` , func ( ) float64 {
return float64 ( m ( ) . SearchTSIDsConcurrencyCurrent )
} )
2020-07-05 18:37:38 +02:00
metrics . NewGauge ( ` vm_search_delays_total ` , func ( ) float64 {
return float64 ( m ( ) . SearchDelays )
} )
2020-05-15 12:44:23 +02:00
metrics . NewGauge ( ` vm_slow_row_inserts_total ` , func ( ) float64 {
return float64 ( m ( ) . SlowRowInserts )
} )
metrics . NewGauge ( ` vm_slow_per_day_index_inserts_total ` , func ( ) float64 {
return float64 ( m ( ) . SlowPerDayIndexInserts )
} )
2020-05-15 13:11:39 +02:00
metrics . NewGauge ( ` vm_slow_metric_name_loads_total ` , func ( ) float64 {
return float64 ( m ( ) . SlowMetricNameLoads )
} )
2020-05-15 12:44:23 +02:00
2021-05-20 13:15:19 +02:00
metrics . NewGauge ( ` vm_hourly_series_limit_rows_dropped_total ` , func ( ) float64 {
return float64 ( m ( ) . HourlySeriesLimitRowsDropped )
} )
metrics . NewGauge ( ` vm_daily_series_limit_rows_dropped_total ` , func ( ) float64 {
return float64 ( m ( ) . DailySeriesLimitRowsDropped )
} )
2020-09-09 22:18:32 +02:00
metrics . NewGauge ( ` vm_timestamps_blocks_merged_total ` , func ( ) float64 {
return float64 ( m ( ) . TimestampsBlocksMerged )
} )
metrics . NewGauge ( ` vm_timestamps_bytes_saved_total ` , func ( ) float64 {
return float64 ( m ( ) . TimestampsBytesSaved )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_rows { type="storage/big"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigRowsCount )
} )
metrics . NewGauge ( ` vm_rows { type="storage/small"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallRowsCount )
} )
metrics . NewGauge ( ` vm_rows { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . ItemsCount )
} )
2019-11-09 22:17:42 +01:00
metrics . NewGauge ( ` vm_date_range_search_calls_total ` , func ( ) float64 {
return float64 ( idbm ( ) . DateRangeSearchCalls )
} )
metrics . NewGauge ( ` vm_date_range_hits_total ` , func ( ) float64 {
return float64 ( idbm ( ) . DateRangeSearchHits )
} )
2019-12-02 19:44:18 +01:00
metrics . NewGauge ( ` vm_missing_metric_names_for_metric_id_total ` , func ( ) float64 {
return float64 ( idbm ( ) . MissingMetricNamesForMetricID )
} )
2019-11-11 12:21:05 +01:00
metrics . NewGauge ( ` vm_date_metric_id_cache_syncs_total ` , func ( ) float64 {
return float64 ( m ( ) . DateMetricIDCacheSyncsCount )
} )
metrics . NewGauge ( ` vm_date_metric_id_cache_resets_total ` , func ( ) float64 {
return float64 ( m ( ) . DateMetricIDCacheResetsCount )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="storage/tsid"} ` , func ( ) float64 {
return float64 ( m ( ) . TSIDCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="storage/metricIDs"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricIDCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="storage/metricName"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricNameCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="storage/date_metricID"} ` , func ( ) float64 {
return float64 ( m ( ) . DateMetricIDCacheSize )
} )
2019-06-19 17:36:47 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="storage/hour_metric_ids"} ` , func ( ) float64 {
return float64 ( m ( ) . HourMetricIDCacheSize )
} )
2020-05-12 00:06:17 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="storage/next_day_metric_ids"} ` , func ( ) float64 {
return float64 ( m ( ) . NextDayMetricIDCacheSize )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="storage/bigIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigIndexBlocksCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="storage/smallIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallIndexBlocksCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="indexdb/dataBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . DataBlocksCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="indexdb/indexBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexBlocksCacheSize )
} )
metrics . NewGauge ( ` vm_cache_entries { type="indexdb/tagFilters"} ` , func ( ) float64 {
return float64 ( idbm ( ) . TagCacheSize )
} )
2019-06-10 13:02:44 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="indexdb/uselessTagFilters"} ` , func ( ) float64 {
return float64 ( idbm ( ) . UselessTagFiltersCacheSize )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="storage/regexps"} ` , func ( ) float64 {
return float64 ( storage . RegexpCacheSize ( ) )
} )
2020-08-06 15:30:15 +02:00
metrics . NewGauge ( ` vm_cache_entries { type="storage/prefetchedMetricIDs"} ` , func ( ) float64 {
2020-01-30 00:59:43 +01:00
return float64 ( m ( ) . PrefetchedMetricIDsSize )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/tsid"} ` , func ( ) float64 {
2019-07-09 23:47:29 +02:00
return float64 ( m ( ) . TSIDCacheSizeBytes )
2019-05-22 23:16:55 +02:00
} )
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/metricIDs"} ` , func ( ) float64 {
2019-07-09 23:47:29 +02:00
return float64 ( m ( ) . MetricIDCacheSizeBytes )
2019-05-22 23:16:55 +02:00
} )
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/metricName"} ` , func ( ) float64 {
2019-07-09 23:47:29 +02:00
return float64 ( m ( ) . MetricNameCacheSizeBytes )
2019-05-22 23:16:55 +02:00
} )
2021-02-08 23:34:18 +01:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/bigIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigIndexBlocksCacheSizeBytes )
} )
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/smallIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallIndexBlocksCacheSizeBytes )
} )
metrics . NewGauge ( ` vm_cache_size_bytes { type="indexdb/dataBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . DataBlocksCacheSizeBytes )
} )
metrics . NewGauge ( ` vm_cache_size_bytes { type="indexdb/indexBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexBlocksCacheSizeBytes )
} )
2019-11-13 16:58:05 +01:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/date_metricID"} ` , func ( ) float64 {
return float64 ( m ( ) . DateMetricIDCacheSizeBytes )
} )
2019-11-13 18:00:02 +01:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/hour_metric_ids"} ` , func ( ) float64 {
return float64 ( m ( ) . HourMetricIDCacheSizeBytes )
} )
2020-05-12 00:06:17 +02:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/next_day_metric_ids"} ` , func ( ) float64 {
return float64 ( m ( ) . NextDayMetricIDCacheSizeBytes )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="indexdb/tagFilters"} ` , func ( ) float64 {
2019-07-09 23:47:29 +02:00
return float64 ( idbm ( ) . TagCacheSizeBytes )
2019-05-22 23:16:55 +02:00
} )
2019-06-10 13:02:44 +02:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="indexdb/uselessTagFilters"} ` , func ( ) float64 {
2019-07-09 23:47:29 +02:00
return float64 ( idbm ( ) . UselessTagFiltersCacheSizeBytes )
2019-06-10 13:02:44 +02:00
} )
2020-01-30 00:59:43 +01:00
metrics . NewGauge ( ` vm_cache_size_bytes { type="storage/prefetchedMetricIDs"} ` , func ( ) float64 {
return float64 ( m ( ) . PrefetchedMetricIDsSizeBytes )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_requests_total { type="storage/tsid"} ` , func ( ) float64 {
return float64 ( m ( ) . TSIDCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="storage/metricIDs"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricIDCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="storage/metricName"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricNameCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="storage/bigIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigIndexBlocksCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="storage/smallIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallIndexBlocksCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="indexdb/dataBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . DataBlocksCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="indexdb/indexBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexBlocksCacheRequests )
} )
metrics . NewGauge ( ` vm_cache_requests_total { type="indexdb/tagFilters"} ` , func ( ) float64 {
return float64 ( idbm ( ) . TagCacheRequests )
} )
2019-06-10 13:02:44 +02:00
metrics . NewGauge ( ` vm_cache_requests_total { type="indexdb/uselessTagFilters"} ` , func ( ) float64 {
return float64 ( idbm ( ) . UselessTagFiltersCacheRequests )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_requests_total { type="storage/regexps"} ` , func ( ) float64 {
return float64 ( storage . RegexpCacheRequests ( ) )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="storage/tsid"} ` , func ( ) float64 {
return float64 ( m ( ) . TSIDCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="storage/metricIDs"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricIDCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="storage/metricName"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricNameCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="storage/bigIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . BigIndexBlocksCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="storage/smallIndexBlocks"} ` , func ( ) float64 {
return float64 ( tm ( ) . SmallIndexBlocksCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="indexdb/dataBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . DataBlocksCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="indexdb/indexBlocks"} ` , func ( ) float64 {
return float64 ( idbm ( ) . IndexBlocksCacheMisses )
} )
metrics . NewGauge ( ` vm_cache_misses_total { type="indexdb/tagFilters"} ` , func ( ) float64 {
return float64 ( idbm ( ) . TagCacheMisses )
} )
2019-06-10 13:02:44 +02:00
metrics . NewGauge ( ` vm_cache_misses_total { type="indexdb/uselessTagFilters"} ` , func ( ) float64 {
return float64 ( idbm ( ) . UselessTagFiltersCacheMisses )
} )
2019-05-22 23:16:55 +02:00
metrics . NewGauge ( ` vm_cache_misses_total { type="storage/regexps"} ` , func ( ) float64 {
return float64 ( storage . RegexpCacheMisses ( ) )
} )
metrics . NewGauge ( ` vm_deleted_metrics_total { type="indexdb"} ` , func ( ) float64 {
return float64 ( idbm ( ) . DeletedMetricsCount )
} )
metrics . NewGauge ( ` vm_cache_collisions_total { type="storage/tsid"} ` , func ( ) float64 {
return float64 ( m ( ) . TSIDCacheCollisions )
} )
metrics . NewGauge ( ` vm_cache_collisions_total { type="storage/metricName"} ` , func ( ) float64 {
return float64 ( m ( ) . MetricNameCacheCollisions )
} )
}
2020-03-10 22:51:50 +01:00
func jsonResponseError ( w http . ResponseWriter , err error ) {
logger . Errorf ( "%s" , err )
w . WriteHeader ( http . StatusInternalServerError )
fmt . Fprintf ( w , ` { "status":"error","msg":%q} ` , err )
}
2020-12-03 20:40:30 +01:00
func usage ( ) {
const s = `
vmstorage stores time series data obtained from vminsert and returns the requested data to vmselect .
2021-04-20 19:16:17 +02:00
See the docs at https : //docs.victoriametrics.com/Cluster-VictoriaMetrics.html .
2020-12-03 20:40:30 +01:00
`
flagutil . Usage ( s )
}