Skip to content

Commit 151e950

Browse files
committed
Merge branch 'master' into 12918-only-arrow-functions
2 parents 0e007d5 + 72ab24f commit 151e950

File tree

111 files changed

+3480
-686
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3480
-686
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* **Alerting**: Notification reminders [#7330](https://github.com/grafana/grafana/issues/7330), thx [@jbaublitz](https://github.com/jbaublitz)
66
* **Dashboard**: TV & Kiosk mode changes, new cycle view mode button in dashboard toolbar [#13025](https://github.com/grafana/grafana/pull/13025)
77
* **OAuth**: Gitlab OAuth with support for filter by groups [#5623](https://github.com/grafana/grafana/issues/5623), thx [@BenoitKnecht](https://github.com/BenoitKnecht)
8+
* **Postgres**: Graphical query builder [#10095](https://github.com/grafana/grafana/issues/10095), thx [svenklemm](https://github.com/svenklemm)
89

910
### New Features
1011

@@ -19,7 +20,9 @@
1920

2021
### Minor
2122

23+
* **Units**: Adds bitcoin axes unit. [#13125](https://github.com/grafana/grafana/pull/13125)
2224
* **GrafanaCli**: Fixed issue with grafana-cli install plugin resulting in corrupt http response from source error. Fixes [#13079](https://github.com/grafana/grafana/issues/13079)
25+
* **Logging**: Reopen log files after receiving a SIGHUP signal [#13112](https://github.com/grafana/grafana/pull/13112), thx [@filewalkwithme](https://github.com/filewalkwithme)
2326
* **Api**: Delete nonexistent datasource should return 404 [#12313](https://github.com/grafana/grafana/issues/12313), thx [@AustinWinstanley](https://github.com/AustinWinstanley)
2427
* **Dashboard**: Fix selecting current dashboard from search should not reload dashboard [#12248](https://github.com/grafana/grafana/issues/12248)
2528
* **Dashboard**: Use uid when linking to dashboards internally in a dashboard [#10705](https://github.com/grafana/grafana/issues/10705)

conf/defaults.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,3 +538,8 @@ container_name =
538538

539539
[external_image_storage.local]
540540
# does not require any configuration
541+
542+
[rendering]
543+
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
544+
server_url =
545+
callback_url =

conf/sample.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,8 @@ log_queries =
460460

461461
[external_image_storage.local]
462462
# does not require any configuration
463+
464+
[rendering]
465+
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
466+
;server_url =
467+
;callback_url =

docs/sources/administration/provisioning.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ Since not all datasources have the same configuration settings we only have the
155155
| tlsSkipVerify | boolean | *All* | Controls whether a client verifies the server's certificate chain and host name. |
156156
| graphiteVersion | string | Graphite | Graphite version |
157157
| timeInterval | string | Elastic, InfluxDB & Prometheus | Lowest interval/step value that should be used for this data source |
158-
| esVersion | number | Elastic | Elasticsearch version as an number (2/5/56) |
158+
| esVersion | number | Elastic | Elasticsearch version as a number (2/5/56) |
159159
| timeField | string | Elastic | Which field that should be used as timestamp |
160160
| interval | string | Elastic | Index date time format |
161161
| authType | string | Cloudwatch | Auth provider. keys/credentials/arn |
@@ -165,6 +165,8 @@ Since not all datasources have the same configuration settings we only have the
165165
| tsdbVersion | string | OpenTSDB | Version |
166166
| tsdbResolution | string | OpenTSDB | Resolution |
167167
| sslmode | string | PostgreSQL | SSLmode. 'disable', 'require', 'verify-ca' or 'verify-full' |
168+
| postgresVersion | number | PostgreSQL | Postgres version as a number (903/904/905/906/1000) meaning v9.3, v9.4, ..., v10 |
169+
| timescaledb | boolean | PostgreSQL | Enable usage of TimescaleDB extension |
168170

169171
#### Secure Json Data
170172

docs/sources/features/datasources/postgres.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ Name | Description
3131
*User* | Database user's login/username
3232
*Password* | Database user's password
3333
*SSL Mode* | This option determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the server.
34-
*TimescaleDB* | With this option enabled Grafana will use TimescaleDB features, e.g. use ```time_bucket``` for grouping by time (only available in Grafana 5.3+).
34+
*Version* | This option determines which functions are available in the query builder (only available in Grafana 5.3+).
35+
*TimescaleDB* | TimescaleDB is a time-series database built as a PostgreSQL extension. If enabled, Grafana will use `time_bucket` in the `$__timeGroup` macro and display TimescaleDB specific aggregate functions in the query builder (only available in Grafana 5.3+).
36+
3537

3638
### Database User Permissions (Important!)
3739

@@ -292,5 +294,6 @@ datasources:
292294
password: "Password!"
293295
jsonData:
294296
sslmode: "disable" # disable/require/verify-ca/verify-full
297+
postgresVersion: 903 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10
295298
timescaledb: false
296299
```

pkg/cmd/grafana-server/main.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,17 @@ func main() {
9696

9797
func listenToSystemSignals(server *GrafanaServerImpl) {
9898
signalChan := make(chan os.Signal, 1)
99-
ignoreChan := make(chan os.Signal, 1)
99+
sighupChan := make(chan os.Signal, 1)
100100

101-
signal.Notify(ignoreChan, syscall.SIGHUP)
101+
signal.Notify(sighupChan, syscall.SIGHUP)
102102
signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGTERM)
103103

104-
select {
105-
case sig := <-signalChan:
106-
server.Shutdown(fmt.Sprintf("System signal: %s", sig))
104+
for {
105+
select {
106+
case _ = <-sighupChan:
107+
log.Reload()
108+
case sig := <-signalChan:
109+
server.Shutdown(fmt.Sprintf("System signal: %s", sig))
110+
}
107111
}
108112
}

pkg/log/file.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,20 @@ func (w *FileLogWriter) Close() {
236236
func (w *FileLogWriter) Flush() {
237237
w.mw.fd.Sync()
238238
}
239+
240+
// Reload file logger
241+
func (w *FileLogWriter) Reload() {
242+
// block Logger's io.Writer
243+
w.mw.Lock()
244+
defer w.mw.Unlock()
245+
246+
// Close
247+
fd := w.mw.fd
248+
fd.Close()
249+
250+
// Open again
251+
err := w.StartLogger()
252+
if err != nil {
253+
fmt.Fprintf(os.Stderr, "Reload StartLogger: %s\n", err)
254+
}
255+
}

pkg/log/handlers.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ package log
33
type DisposableHandler interface {
44
Close()
55
}
6+
7+
type ReloadableHandler interface {
8+
Reload()
9+
}

pkg/log/log.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ import (
2121

2222
var Root log15.Logger
2323
var loggersToClose []DisposableHandler
24+
var loggersToReload []ReloadableHandler
2425
var filters map[string]log15.Lvl
2526

2627
func init() {
2728
loggersToClose = make([]DisposableHandler, 0)
29+
loggersToReload = make([]ReloadableHandler, 0)
2830
Root = log15.Root()
2931
Root.SetHandler(log15.DiscardHandler())
3032
}
@@ -115,6 +117,12 @@ func Close() {
115117
loggersToClose = make([]DisposableHandler, 0)
116118
}
117119

120+
func Reload() {
121+
for _, logger := range loggersToReload {
122+
logger.Reload()
123+
}
124+
}
125+
118126
func GetLogLevelFor(name string) Lvl {
119127
if level, ok := filters[name]; ok {
120128
switch level {
@@ -230,6 +238,7 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) {
230238
fileHandler.Init()
231239

232240
loggersToClose = append(loggersToClose, fileHandler)
241+
loggersToReload = append(loggersToReload, fileHandler)
233242
handler = fileHandler
234243
case "syslog":
235244
sysLogHandler := NewSyslog(sec, format)

pkg/services/rendering/http_mode.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package rendering
22

33
import (
44
"context"
5+
"fmt"
56
"io"
67
"net"
78
"net/http"
@@ -20,25 +21,24 @@ var netTransport = &http.Transport{
2021
TLSHandshakeTimeout: 5 * time.Second,
2122
}
2223

24+
var netClient = &http.Client{
25+
Transport: netTransport,
26+
}
27+
2328
func (rs *RenderingService) renderViaHttp(ctx context.Context, opts Opts) (*RenderResult, error) {
2429
filePath := rs.getFilePathForNewImage()
2530

26-
var netClient = &http.Client{
27-
Timeout: opts.Timeout,
28-
Transport: netTransport,
29-
}
30-
3131
rendererUrl, err := url.Parse(rs.Cfg.RendererUrl)
3232
if err != nil {
3333
return nil, err
3434
}
3535

3636
queryParams := rendererUrl.Query()
3737
queryParams.Add("url", rs.getURL(opts.Path))
38-
queryParams.Add("renderKey", rs.getRenderKey(opts.UserId, opts.OrgId, opts.OrgRole))
38+
queryParams.Add("renderKey", rs.getRenderKey(opts.OrgId, opts.UserId, opts.OrgRole))
3939
queryParams.Add("width", strconv.Itoa(opts.Width))
4040
queryParams.Add("height", strconv.Itoa(opts.Height))
41-
queryParams.Add("domain", rs.getLocalDomain())
41+
queryParams.Add("domain", rs.domain)
4242
queryParams.Add("timezone", isoTimeOffsetToPosixTz(opts.Timezone))
4343
queryParams.Add("encoding", opts.Encoding)
4444
queryParams.Add("timeout", strconv.Itoa(int(opts.Timeout.Seconds())))
@@ -49,20 +49,48 @@ func (rs *RenderingService) renderViaHttp(ctx context.Context, opts Opts) (*Rend
4949
return nil, err
5050
}
5151

52+
reqContext, cancel := context.WithTimeout(ctx, opts.Timeout+time.Second*2)
53+
defer cancel()
54+
55+
req = req.WithContext(reqContext)
56+
5257
// make request to renderer server
5358
resp, err := netClient.Do(req)
5459
if err != nil {
55-
return nil, err
60+
rs.log.Error("Failed to send request to remote rendering service.", "error", err)
61+
return nil, fmt.Errorf("Failed to send request to remote rendering service. %s", err)
5662
}
5763

5864
// save response to file
5965
defer resp.Body.Close()
66+
67+
// check for timeout first
68+
if reqContext.Err() == context.DeadlineExceeded {
69+
rs.log.Info("Rendering timed out")
70+
return nil, ErrTimeout
71+
}
72+
73+
// if we didnt get a 200 response, something went wrong.
74+
if resp.StatusCode != http.StatusOK {
75+
rs.log.Error("Remote rendering request failed", "error", resp.Status)
76+
return nil, fmt.Errorf("Remote rendering request failed. %d: %s", resp.StatusCode, resp.Status)
77+
}
78+
6079
out, err := os.Create(filePath)
6180
if err != nil {
6281
return nil, err
6382
}
6483
defer out.Close()
65-
io.Copy(out, resp.Body)
84+
_, err = io.Copy(out, resp.Body)
85+
if err != nil {
86+
// check that we didnt timeout while receiving the response.
87+
if reqContext.Err() == context.DeadlineExceeded {
88+
rs.log.Info("Rendering timed out")
89+
return nil, ErrTimeout
90+
}
91+
rs.log.Error("Remote rendering request failed", "error", err)
92+
return nil, fmt.Errorf("Remote rendering request failed. %s", err)
93+
}
6694

6795
return &RenderResult{FilePath: filePath}, err
6896
}

0 commit comments

Comments
 (0)