Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
6b2a4fe8
Commit
6b2a4fe8
authored
Jun 02, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(instrumentation): work on settings model for internal metrics publishing, #4696
parent
74101eaf
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
130 additions
and
37 deletions
+130
-37
conf/defaults.ini
+3
-0
conf/sample.ini
+3
-0
pkg/cmd/grafana-server/main.go
+1
-4
pkg/cmd/grafana-server/web.go
+1
-1
pkg/metrics/publish.go
+17
-18
pkg/metrics/publishers/graphite.go
+25
-14
pkg/metrics/settings.go
+47
-0
pkg/setting/setting.go
+24
-0
pkg/setting/setting_test.go
+9
-0
No files found.
conf/defaults.ini
View file @
6b2a4fe8
...
@@ -6,6 +6,9 @@
...
@@ -6,6 +6,9 @@
# possible values : production, development
# possible values : production, development
app_mode
=
production
app_mode
=
production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
instance_name
=
${HOSTNAME}
#################################### Paths ####################################
#################################### Paths ####################################
[paths]
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
...
...
conf/sample.ini
View file @
6b2a4fe8
...
@@ -6,6 +6,9 @@
...
@@ -6,6 +6,9 @@
# possible values : production, development
# possible values : production, development
; app_mode = production
; app_mode = production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
; instance_name = ${HOSTNAME}
#################################### Paths ####################################
#################################### Paths ####################################
[paths]
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
...
...
pkg/cmd/grafana-server/main.go
View file @
6b2a4fe8
...
@@ -64,15 +64,12 @@ func main() {
...
@@ -64,15 +64,12 @@ func main() {
social
.
NewOAuthService
()
social
.
NewOAuthService
()
eventpublisher
.
Init
()
eventpublisher
.
Init
()
plugins
.
Init
()
plugins
.
Init
()
metrics
.
Init
()
if
err
:=
notifications
.
Init
();
err
!=
nil
{
if
err
:=
notifications
.
Init
();
err
!=
nil
{
log
.
Fatal
(
3
,
"Notification service failed to initialize"
,
err
)
log
.
Fatal
(
3
,
"Notification service failed to initialize"
,
err
)
}
}
if
setting
.
ReportingEnabled
{
go
metrics
.
StartUsageReportLoop
()
}
StartServer
()
StartServer
()
exitChan
<-
0
exitChan
<-
0
}
}
...
...
pkg/cmd/grafana-server/web.go
View file @
6b2a4fe8
...
@@ -31,7 +31,7 @@ func newMacaron() *macaron.Macaron {
...
@@ -31,7 +31,7 @@ func newMacaron() *macaron.Macaron {
for
_
,
route
:=
range
plugins
.
StaticRoutes
{
for
_
,
route
:=
range
plugins
.
StaticRoutes
{
pluginRoute
:=
path
.
Join
(
"/public/plugins/"
,
route
.
PluginId
)
pluginRoute
:=
path
.
Join
(
"/public/plugins/"
,
route
.
PluginId
)
log
.
Info
(
"Plugins: Adding route %s -> %s"
,
pluginRoute
,
route
.
Directory
)
log
.
Debug
(
"Plugins: Adding route %s -> %s"
,
pluginRoute
,
route
.
Directory
)
mapStatic
(
m
,
route
.
Directory
,
""
,
pluginRoute
)
mapStatic
(
m
,
route
.
Directory
,
""
,
pluginRoute
)
}
}
...
...
pkg/metrics/
send
.go
→
pkg/metrics/
publish
.go
View file @
6b2a4fe8
...
@@ -9,40 +9,36 @@ import (
...
@@ -9,40 +9,36 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/metrics/senders"
m
"github.com/grafana/grafana/pkg/models"
m
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/setting"
)
)
type
MetricSender
interface
{
func
Init
()
{
Send
(
metrics
map
[
string
]
interface
{})
error
go
instrumentationLoop
()
}
}
func
StartUsageReport
Loop
()
chan
struct
{}
{
func
instrumentation
Loop
()
chan
struct
{}
{
M_Instance_Start
.
Inc
(
1
)
M_Instance_Start
.
Inc
(
1
)
hourTicker
:=
time
.
NewTicker
(
time
.
Hour
*
24
)
settings
:=
readSettings
()
secondTicker
:=
time
.
NewTicker
(
time
.
Second
*
10
)
sender
:=
&
receiver
.
GraphiteSender
{
onceEveryDayTick
:=
time
.
NewTicker
(
time
.
Hour
*
24
)
Host
:
"localhost"
,
secondTicker
:=
time
.
NewTicker
(
time
.
Second
*
time
.
Duration
(
settings
.
IntervalSeconds
))
Port
:
"2003"
,
Protocol
:
"tcp"
,
Prefix
:
"grafana."
,
}
for
{
for
{
select
{
select
{
case
<-
hourTicker
.
C
:
case
<-
onceEveryDayTick
.
C
:
sendUsageStats
()
sendUsageStats
()
case
<-
secondTicker
.
C
:
case
<-
secondTicker
.
C
:
sendMetricUsage
(
sender
)
if
settings
.
Enabled
{
sendMetrics
(
settings
)
}
}
}
}
}
}
}
func
sendMetric
Usage
(
sender
MetricSender
)
{
func
sendMetric
s
(
settings
*
MetricSettings
)
{
metrics
:=
map
[
string
]
interface
{}{}
metrics
:=
map
[
string
]
interface
{}{}
MetricStats
.
Each
(
func
(
name
string
,
i
interface
{})
{
MetricStats
.
Each
(
func
(
name
string
,
i
interface
{})
{
...
@@ -63,13 +59,16 @@ func sendMetricUsage(sender MetricSender) {
...
@@ -63,13 +59,16 @@ func sendMetricUsage(sender MetricSender) {
}
}
})
})
err
:=
sender
.
Send
(
metrics
)
for
_
,
publisher
:=
range
settings
.
Publishers
{
if
err
!=
nil
{
publisher
.
Publish
(
metrics
)
log
.
Error
(
1
,
"Failed to send metrics:"
,
err
)
}
}
}
}
func
sendUsageStats
()
{
func
sendUsageStats
()
{
if
!
setting
.
ReportingEnabled
{
return
}
log
.
Trace
(
"Sending anonymous usage stats to stats.grafana.org"
)
log
.
Trace
(
"Sending anonymous usage stats to stats.grafana.org"
)
version
:=
strings
.
Replace
(
setting
.
BuildVersion
,
"."
,
"_"
,
-
1
)
version
:=
strings
.
Replace
(
setting
.
BuildVersion
,
"."
,
"_"
,
-
1
)
...
...
pkg/metrics/
send
ers/graphite.go
→
pkg/metrics/
publish
ers/graphite.go
View file @
6b2a4fe8
package
receiver
package
publishers
import
(
import
(
"bytes"
"bytes"
"fmt"
"fmt"
"github.com/grafana/grafana/pkg/log"
"net"
"net"
"time"
"time"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/setting"
)
)
type
GraphiteSender
struct
{
type
GraphitePublisher
struct
{
Host
string
Address
string
Port
string
Protocol
string
Protocol
string
Prefix
string
Prefix
string
}
}
func
(
this
*
GraphiteSender
)
Send
(
metrics
map
[
string
]
interface
{})
error
{
func
CreateGraphitePublisher
()
(
*
GraphitePublisher
,
error
)
{
log
.
Debug
(
"GraphiteSender: Sending metrics to graphite"
)
graphiteSection
,
err
:=
setting
.
Cfg
.
GetSection
(
"metrics.graphite"
)
if
err
!=
nil
{
return
nil
,
nil
}
address
:=
fmt
.
Sprintf
(
"%s:%s"
,
this
.
Host
,
this
.
Port
)
graphiteReceiver
:=
&
GraphitePublisher
{}
conn
,
err
:=
net
.
DialTimeout
(
this
.
Protocol
,
address
,
time
.
Second
*
5
)
graphiteReceiver
.
Protocol
=
"tcp"
graphiteReceiver
.
Address
=
graphiteSection
.
Key
(
"address"
)
.
MustString
(
"localhost:2003"
)
graphiteReceiver
.
Prefix
=
graphiteSection
.
Key
(
"prefix"
)
.
MustString
(
"service.grafana.%(instance_name)s"
)
return
graphiteReceiver
,
nil
}
func
(
this
*
GraphitePublisher
)
Publish
(
metrics
map
[
string
]
interface
{})
{
conn
,
err
:=
net
.
DialTimeout
(
this
.
Protocol
,
this
.
Address
,
time
.
Second
*
5
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Graphite Sender: Failed to connec to %s!"
,
err
)
log
.
Error
(
3
,
"Metrics: GraphitePublisher: Failed to connect to %s!"
,
err
)
return
}
}
buf
:=
bytes
.
NewBufferString
(
""
)
buf
:=
bytes
.
NewBufferString
(
""
)
...
@@ -30,15 +43,13 @@ func (this *GraphiteSender) Send(metrics map[string]interface{}) error {
...
@@ -30,15 +43,13 @@ func (this *GraphiteSender) Send(metrics map[string]interface{}) error {
for
key
,
value
:=
range
metrics
{
for
key
,
value
:=
range
metrics
{
metricName
:=
this
.
Prefix
+
key
metricName
:=
this
.
Prefix
+
key
line
:=
fmt
.
Sprintf
(
"%s %d %d
\n
"
,
metricName
,
value
,
now
)
line
:=
fmt
.
Sprintf
(
"%s %d %d
\n
"
,
metricName
,
value
,
now
)
log
.
Debug
(
"SendMetric: sending %s"
,
line
)
buf
.
WriteString
(
line
)
buf
.
WriteString
(
line
)
}
}
log
.
Trace
(
"Metrics: GraphitePublisher.Publish()
\n
%s"
,
buf
)
_
,
err
=
conn
.
Write
(
buf
.
Bytes
())
_
,
err
=
conn
.
Write
(
buf
.
Bytes
())
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Graphite Send
er: Failed to send metrics! %s"
,
err
)
log
.
Error
(
3
,
"Metrics: GraphitePublish
er: Failed to send metrics! %s"
,
err
)
}
}
return
nil
}
}
pkg/metrics/settings.go
0 → 100644
View file @
6b2a4fe8
package
metrics
import
(
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/metrics/publishers"
"github.com/grafana/grafana/pkg/setting"
)
type
MetricPublisher
interface
{
Publish
(
metrics
map
[
string
]
interface
{})
}
type
MetricSettings
struct
{
Enabled
bool
IntervalSeconds
int64
Publishers
[]
MetricPublisher
}
func
readSettings
()
*
MetricSettings
{
var
settings
=
&
MetricSettings
{
Enabled
:
false
,
Publishers
:
make
([]
MetricPublisher
,
0
),
}
var
section
,
err
=
setting
.
Cfg
.
GetSection
(
"metrics"
)
if
err
!=
nil
{
log
.
Fatal
(
3
,
"Unable to find metrics config section"
)
return
nil
}
settings
.
Enabled
=
section
.
Key
(
"enabled"
)
.
MustBool
(
false
)
settings
.
IntervalSeconds
=
section
.
Key
(
"interval_seconds"
)
.
MustInt64
(
10
)
if
!
settings
.
Enabled
{
return
settings
}
if
graphitePublisher
,
err
:=
publishers
.
CreateGraphitePublisher
();
err
!=
nil
{
log
.
Error
(
3
,
"Metrics: Failed to init Graphite metric publisher"
,
err
)
}
else
if
graphitePublisher
!=
nil
{
log
.
Info
(
"Metrics: Internal metrics publisher Graphite initialized"
)
settings
.
Publishers
=
append
(
settings
.
Publishers
,
graphitePublisher
)
}
return
settings
}
pkg/setting/setting.go
View file @
6b2a4fe8
...
@@ -40,6 +40,7 @@ var (
...
@@ -40,6 +40,7 @@ var (
Env
string
=
DEV
Env
string
=
DEV
AppUrl
string
AppUrl
string
AppSubUrl
string
AppSubUrl
string
InstanceName
string
// build
// build
BuildVersion
string
BuildVersion
string
...
@@ -259,6 +260,12 @@ func evalEnvVarExpression(value string) string {
...
@@ -259,6 +260,12 @@ func evalEnvVarExpression(value string) string {
envVar
=
strings
.
TrimPrefix
(
envVar
,
"${"
)
envVar
=
strings
.
TrimPrefix
(
envVar
,
"${"
)
envVar
=
strings
.
TrimSuffix
(
envVar
,
"}"
)
envVar
=
strings
.
TrimSuffix
(
envVar
,
"}"
)
envValue
:=
os
.
Getenv
(
envVar
)
envValue
:=
os
.
Getenv
(
envVar
)
// if env variable is hostname and it is emtpy use os.Hostname as default
if
envVar
==
"HOSTNAME"
&&
envValue
==
""
{
envValue
,
_
=
os
.
Hostname
()
}
return
envValue
return
envValue
})
})
}
}
...
@@ -395,11 +402,28 @@ func validateStaticRootPath() error {
...
@@ -395,11 +402,28 @@ func validateStaticRootPath() error {
return
fmt
.
Errorf
(
"Failed to detect generated css or javascript files in static root (%s), have you executed default grunt task?"
,
StaticRootPath
)
return
fmt
.
Errorf
(
"Failed to detect generated css or javascript files in static root (%s), have you executed default grunt task?"
,
StaticRootPath
)
}
}
// func readInstanceName() string {
// hostname, _ := os.Hostname()
// if hostname == "" {
// hostname = "hostname_unknown"
// }
//
// instanceName := Cfg.Section("").Key("instance_name").MustString("")
// if instanceName = "" {
// // set value as it might be used in other places
// Cfg.Section("").Key("instance_name").SetValue(hostname)
// instanceName = hostname
// }
//
// return
// }
func
NewConfigContext
(
args
*
CommandLineArgs
)
error
{
func
NewConfigContext
(
args
*
CommandLineArgs
)
error
{
setHomePath
(
args
)
setHomePath
(
args
)
loadConfiguration
(
args
)
loadConfiguration
(
args
)
Env
=
Cfg
.
Section
(
""
)
.
Key
(
"app_mode"
)
.
MustString
(
"development"
)
Env
=
Cfg
.
Section
(
""
)
.
Key
(
"app_mode"
)
.
MustString
(
"development"
)
InstanceName
=
Cfg
.
Section
(
""
)
.
Key
(
"instance_name"
)
.
MustString
(
"unknown_instance_name"
)
PluginsPath
=
Cfg
.
Section
(
"paths"
)
.
Key
(
"plugins"
)
.
String
()
PluginsPath
=
Cfg
.
Section
(
"paths"
)
.
Key
(
"plugins"
)
.
String
()
server
:=
Cfg
.
Section
(
"server"
)
server
:=
Cfg
.
Section
(
"server"
)
...
...
pkg/setting/setting_test.go
View file @
6b2a4fe8
...
@@ -89,5 +89,14 @@ func TestLoadingSettings(t *testing.T) {
...
@@ -89,5 +89,14 @@ func TestLoadingSettings(t *testing.T) {
So
(
DataPath
,
ShouldEqual
,
"/tmp/env_override"
)
So
(
DataPath
,
ShouldEqual
,
"/tmp/env_override"
)
})
})
Convey
(
"instance_name default to hostname even if hostname env is emtpy"
,
func
()
{
NewConfigContext
(
&
CommandLineArgs
{
HomePath
:
"../../"
,
})
hostname
,
_
:=
os
.
Hostname
()
So
(
InstanceName
,
ShouldEqual
,
hostname
)
})
})
})
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment