Skip to content

Commit 4992aa7

Browse files
committed
change dinamically the interval duration
Signed-off-by: Augustin Husson <husson.augustin@gmail.com>
1 parent 8489ff4 commit 4992aa7

File tree

5 files changed

+106
-69
lines changed

5 files changed

+106
-69
lines changed

cmd/promql-langserver/promql-langserver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func main() {
5858

5959
logger = kitlog.NewSyncLogger(logger)
6060

61-
handler, err := rest.CreateInstHandler(context.Background(), prometheusClient, logger, config.Interval)
61+
handler, err := rest.CreateInstHandler(context.Background(), prometheusClient, logger, config.MetadataLookbackInterval)
6262
if err != nil {
6363
log.Fatal(err)
6464
}

langserver/completion.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ func (s *server) completeLabel(ctx context.Context, completions *[]protocol.Comp
312312
if vs != nil {
313313
metricName = vs.Name
314314
}
315-
allNames, err := s.metadataService.LabelNames(ctx, metricName, time.Now().Add(time.Duration(-1*s.config.Interval)), time.Now())
315+
allNames, err := s.metadataService.LabelNames(ctx, metricName, time.Now().Add(time.Duration(-1*s.config.MetadataLookbackInterval)), time.Now())
316316
if err != nil {
317317
// nolint: errcheck
318318
s.client.LogMessage(s.lifetime, &protocol.LogMessageParams{
@@ -355,7 +355,7 @@ OUTER:
355355

356356
// nolint: funlen
357357
func (s *server) completeLabelValue(ctx context.Context, completions *[]protocol.CompletionItem, location *cache.Location, labelName string) error {
358-
labelValues, err := s.metadataService.LabelValues(ctx, labelName, time.Now().Add(time.Duration(-1*s.config.Interval)), time.Now())
358+
labelValues, err := s.metadataService.LabelValues(ctx, labelName, time.Now().Add(time.Duration(-1*s.config.MetadataLookbackInterval)), time.Now())
359359
if err != nil {
360360
// nolint: errcheck
361361
s.client.LogMessage(s.lifetime, &protocol.LogMessageParams{

langserver/config.go

Lines changed: 88 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ type Config struct {
3636
LogFormat LogFormat `yaml:"log_format"`
3737
PrometheusURL string `yaml:"prometheus_url"`
3838
RESTAPIPort uint64 `yaml:"rest_api_port"`
39-
// Interval is the time in second used to retrieve label and metrics from Prometheus
40-
Interval model.Duration `yaml:"interval"`
39+
// MetadataLookbackInterval is the time in second used to retrieve label and metrics from Prometheus
40+
MetadataLookbackInterval model.Duration `yaml:"metadataLookbackInterval"`
4141
}
4242

4343
// LogFormat is the type used for describing the format of logs.
@@ -55,7 +55,6 @@ var mapLogFormat = map[LogFormat]bool{ // nolint: gochecknoglobals
5555
TextFormat: true,
5656
}
5757

58-
// Parameterizable
5958
// UnmarshalYAML overrides a function used internally by the yaml.v3 lib.
6059
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
6160
tmp := &Config{}
@@ -78,8 +77,8 @@ func (c *Config) unmarshalENV() error {
7877
PrometheusURL string
7978
// the envconfig lib is not able to convert an empty string to the value 0
8079
// so we have to convert it manually
81-
RESTAPIPort string
82-
Interval string
80+
RESTAPIPort string
81+
MetadataLookbackInterval string
8382
}{}
8483
if err := envconfig.Process(prefix, conf); err != nil {
8584
return err
@@ -91,9 +90,9 @@ func (c *Config) unmarshalENV() error {
9190
return parseError
9291
}
9392
}
94-
if len(conf.Interval) > 0 {
93+
if len(conf.MetadataLookbackInterval) > 0 {
9594
var parseError error
96-
c.Interval, parseError = model.ParseDuration(conf.Interval)
95+
c.MetadataLookbackInterval, parseError = model.ParseDuration(conf.MetadataLookbackInterval)
9796
if parseError != nil {
9897
return parseError
9998
}
@@ -120,8 +119,8 @@ func (c *Config) Validate() error {
120119
// default value
121120
c.LogFormat = TextFormat
122121
}
123-
if c.Interval <= 0 {
124-
c.Interval = defaultInterval
122+
if c.MetadataLookbackInterval <= 0 {
123+
c.MetadataLookbackInterval = defaultInterval
125124
}
126125

127126
return nil
@@ -155,41 +154,91 @@ func readConfigFromENV() (*Config, error) {
155154

156155
// DidChangeConfiguration is required by the protocol.Server interface.
157156
func (s *server) DidChangeConfiguration(ctx context.Context, params *protocol.DidChangeConfigurationParams) error {
158-
langserverAddressConfigPath := []string{"promql", "url"}
157+
if params == nil {
158+
return nil
159+
}
160+
// nolint: errcheck
161+
s.client.LogMessage(
162+
s.lifetime,
163+
&protocol.LogMessageParams{
164+
Type: protocol.Info,
165+
Message: fmt.Sprintf("Received notification change: %v\n", params),
166+
})
167+
168+
setting := params.Settings
169+
170+
// the struct expected is the following
171+
// promql:
172+
// url: http://
173+
// interval: 3w
174+
m, ok := setting.(map[string]map[string]string)
175+
if !ok {
176+
// nolint: errcheck
177+
s.client.LogMessage(ctx, &protocol.LogMessageParams{
178+
Type: protocol.Error,
179+
Message: fmt.Sprint("unexpected format of the configuration"),
180+
})
181+
return nil
182+
}
183+
config, ok := m["promql"]
184+
if !ok {
185+
// nolint: errcheck
186+
s.client.LogMessage(ctx, &protocol.LogMessageParams{
187+
Type: protocol.Error,
188+
Message: fmt.Sprint("promQL key not found"),
189+
})
190+
return nil
191+
}
159192

160-
if params != nil {
193+
if err := s.setURLFromChangeConfiguration(config); err != nil {
161194
// nolint: errcheck
162-
s.client.LogMessage(
163-
s.lifetime,
164-
&protocol.LogMessageParams{
165-
Type: protocol.Info,
166-
Message: fmt.Sprintf("Received notification change: %v\n", params),
167-
})
168-
169-
setting := params.Settings
170-
171-
for _, e := range langserverAddressConfigPath {
172-
m, ok := setting.(map[string]interface{})
173-
if !ok {
174-
break
175-
}
176-
177-
setting, ok = m[e]
178-
if !ok {
179-
break
180-
}
181-
}
195+
s.client.LogMessage(ctx, &protocol.LogMessageParams{
196+
Type: protocol.Info,
197+
Message: err.Error(),
198+
})
199+
}
182200

183-
if str, ok := setting.(string); ok {
184-
if err := s.connectPrometheus(str); err != nil {
185-
// nolint: errcheck
186-
s.client.LogMessage(ctx, &protocol.LogMessageParams{
187-
Type: protocol.Info,
188-
Message: err.Error(),
189-
})
190-
}
201+
if err := s.setMetadataLookbackIntervalFromChangeConfiguration(config); err != nil {
202+
// nolint: errcheck
203+
s.client.LogMessage(ctx, &protocol.LogMessageParams{
204+
Type: protocol.Info,
205+
Message: err.Error(),
206+
})
207+
}
208+
return nil
209+
}
210+
211+
func (s *server) setURLFromChangeConfiguration(settings map[string]string) error {
212+
if promURL, ok := settings["url"]; ok {
213+
if _, err := url.Parse(promURL); err != nil {
214+
return err
215+
}
216+
if err := s.connectPrometheus(promURL); err != nil {
217+
return err
191218
}
192219
}
220+
return nil
221+
}
193222

223+
func (s *server) connectPrometheus(url string) error {
224+
if err := s.metadataService.ChangeDataSource(url); err != nil {
225+
// nolint: errcheck
226+
s.client.ShowMessage(s.lifetime, &protocol.ShowMessageParams{
227+
Type: protocol.Error,
228+
Message: fmt.Sprintf("Failed to connect to Prometheus at %s:\n\n%s ", url, err.Error()),
229+
})
230+
return err
231+
}
232+
return nil
233+
}
234+
235+
func (s *server) setMetadataLookbackIntervalFromChangeConfiguration(settings map[string]string) error {
236+
if interval, ok := settings["metadataLookbackInterval"]; ok {
237+
duration, err := model.ParseDuration(interval)
238+
if err != nil {
239+
return err
240+
}
241+
s.config.MetadataLookbackInterval = duration
242+
}
194243
return nil
195244
}

langserver/config_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,25 @@ func TestUnmarshalENV(t *testing.T) {
3030
title: "empty config",
3131
variables: map[string]string{},
3232
expected: &Config{
33-
LogFormat: TextFormat,
34-
Interval: defaultInterval,
33+
LogFormat: TextFormat,
34+
MetadataLookbackInterval: defaultInterval,
3535
},
3636
},
3737
{
3838
title: "full config",
3939
variables: map[string]string{
40-
"LANGSERVER_RPCTRACE": "text",
41-
"LANGSERVER_PROMETHEUSURL": "http://localhost:9090",
42-
"LANGSERVER_RESTAPIPORT": "8080",
43-
"LANGSERVER_LOGFORMAT": "json",
44-
"LANGSERVER_INTERVAL": "1w",
40+
"LANGSERVER_RPCTRACE": "text",
41+
"LANGSERVER_PROMETHEUSURL": "http://localhost:9090",
42+
"LANGSERVER_RESTAPIPORT": "8080",
43+
"LANGSERVER_LOGFORMAT": "json",
44+
"LANGSERVER_METADATALOOKBACKINTERVAL": "1w",
4545
},
4646
expected: &Config{
47-
RPCTrace: "text",
48-
PrometheusURL: "http://localhost:9090",
49-
RESTAPIPort: 8080,
50-
LogFormat: JSONFormat,
51-
Interval: 604800000000000,
47+
RPCTrace: "text",
48+
PrometheusURL: "http://localhost:9090",
49+
RESTAPIPort: 8080,
50+
LogFormat: JSONFormat,
51+
MetadataLookbackInterval: 604800000000000,
5252
},
5353
},
5454
}

langserver/server.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ func (s Server) Run() error {
8686
// "locked down" in this case means, that the instance cannot send or receive any JSONRPC communication. Logging messages that the instance tries to send over JSONRPC are redirected to stderr.
8787
func CreateHeadlessServer(ctx context.Context, metadataService promClient.MetadataService, logger log.Logger, interval model.Duration) (HeadlessServer, error) {
8888
conf := &Config{
89-
PrometheusURL: metadataService.GetURL(),
90-
Interval: interval,
89+
PrometheusURL: metadataService.GetURL(),
90+
MetadataLookbackInterval: interval,
9191
}
9292
if interval <= 0 {
93-
conf.Interval = defaultInterval
93+
conf.MetadataLookbackInterval = defaultInterval
9494
}
9595
s := &server{
9696
client: &headlessClient{logger: logger},
@@ -146,18 +146,6 @@ func ServerFromStream(ctx context.Context, stream jsonrpc2.Stream, config *Confi
146146
return ctx, Server{s}
147147
}
148148

149-
func (s *server) connectPrometheus(url string) error {
150-
if err := s.metadataService.ChangeDataSource(url); err != nil {
151-
// nolint: errcheck
152-
s.client.ShowMessage(s.lifetime, &protocol.ShowMessageParams{
153-
Type: protocol.Error,
154-
Message: fmt.Sprintf("Failed to connect to Prometheus at %s:\n\n%s ", url, err.Error()),
155-
})
156-
return err
157-
}
158-
return nil
159-
}
160-
161149
// RunTCPServer generates a server listening on the provided TCP Address, creating a new language Server
162150
// instance using plain HTTP for every connection.
163151
func RunTCPServer(ctx context.Context, addr string, config *Config) error {

0 commit comments

Comments
 (0)