Просмотр исходного кода

Merge pull request #1 from grafana/master

sync
Charlie Lewis 8 лет назад
Родитель
Сommit
dbc0ff9739
100 измененных файлов с 3027 добавлено и 489 удалено
  1. 0 3
      .bowerrc
  2. 3 3
      .bra.toml
  3. 5 5
      .editorconfig
  4. 0 3
      .floo
  5. 0 12
      .flooignore
  6. 8 9
      .github/ISSUE_TEMPLATE.md
  7. 3 1
      .github/PULL_REQUEST_TEMPLATE.md
  8. 17 2
      .gitignore
  9. 0 10
      .hooks/pre-commit
  10. 0 21
      .jsfmtrc
  11. 1 1
      .jshintrc
  12. 500 4
      CHANGELOG.md
  13. 46 0
      CODE_OF_CONDUCT.md
  14. 4 3
      Gruntfile.js
  15. 1 1
      LICENSE.md
  16. 2 2
      Makefile
  17. 28 0
      PLUGIN_DEV.md
  18. 48 99
      README.md
  19. 36 0
      ROADMAP.md
  20. 21 5
      appveyor.yml
  21. 0 25
      bower.json
  22. 79 46
      build.go
  23. 34 8
      circle.yml
  24. 13 0
      codecov.yml
  25. 86 38
      conf/defaults.ini
  26. 5 3
      conf/ldap.toml
  27. 77 39
      conf/sample.ini
  28. 11 0
      docker/blocks/collectd/docker-compose.yaml
  29. 0 11
      docker/blocks/collectd/fig
  30. 8 0
      docker/blocks/elastic/docker-compose.yaml
  31. 0 8
      docker/blocks/elastic/fig
  32. 8 0
      docker/blocks/elastic1/docker-compose.yaml
  33. 2 0
      docker/blocks/elastic1/elasticsearch.yml
  34. 8 0
      docker/blocks/elastic5/docker-compose.yaml
  35. 2 0
      docker/blocks/elastic5/elasticsearch.yml
  36. 2 0
      docker/blocks/graphite/Dockerfile
  37. 16 0
      docker/blocks/graphite/docker-compose.yaml
  38. 0 17
      docker/blocks/graphite/fig
  39. 93 0
      docker/blocks/graphite1/Dockerfile
  40. 11 0
      docker/blocks/graphite1/conf/etc/logrotate.d/graphite-statsd
  41. 36 0
      docker/blocks/graphite1/conf/etc/my_init.d/01_conf_init.sh
  42. 96 0
      docker/blocks/graphite1/conf/etc/nginx/nginx.conf
  43. 31 0
      docker/blocks/graphite1/conf/etc/nginx/sites-enabled/graphite-statsd.conf
  44. 4 0
      docker/blocks/graphite1/conf/etc/service/carbon-aggregator/run
  45. 4 0
      docker/blocks/graphite1/conf/etc/service/carbon/run
  46. 3 0
      docker/blocks/graphite1/conf/etc/service/graphite/run
  47. 4 0
      docker/blocks/graphite1/conf/etc/service/nginx/run
  48. 4 0
      docker/blocks/graphite1/conf/etc/service/statsd/run
  49. 35 0
      docker/blocks/graphite1/conf/opt/graphite/conf/aggregation-rules.conf
  50. 5 0
      docker/blocks/graphite1/conf/opt/graphite/conf/blacklist.conf
  51. 75 0
      docker/blocks/graphite1/conf/opt/graphite/conf/carbon.amqp.conf
  52. 359 0
      docker/blocks/graphite1/conf/opt/graphite/conf/carbon.conf
  53. 57 0
      docker/blocks/graphite1/conf/opt/graphite/conf/dashboard.conf
  54. 38 0
      docker/blocks/graphite1/conf/opt/graphite/conf/graphTemplates.conf
  55. 21 0
      docker/blocks/graphite1/conf/opt/graphite/conf/relay-rules.conf
  56. 18 0
      docker/blocks/graphite1/conf/opt/graphite/conf/rewrite-rules.conf
  57. 43 0
      docker/blocks/graphite1/conf/opt/graphite/conf/storage-aggregation.conf
  58. 17 0
      docker/blocks/graphite1/conf/opt/graphite/conf/storage-schemas.conf
  59. 6 0
      docker/blocks/graphite1/conf/opt/graphite/conf/whitelist.conf
  60. 94 0
      docker/blocks/graphite1/conf/opt/graphite/webapp/graphite/app_settings.py
  61. 215 0
      docker/blocks/graphite1/conf/opt/graphite/webapp/graphite/local_settings.py
  62. 6 0
      docker/blocks/graphite1/conf/opt/statsd/config.js
  63. 26 0
      docker/blocks/graphite1/conf/usr/local/bin/django_admin_init.exp
  64. 3 0
      docker/blocks/graphite1/conf/usr/local/bin/manage.sh
  65. 16 0
      docker/blocks/graphite1/docker-compose.yaml
  66. 76 0
      docker/blocks/graphite1/files/carbon.conf
  67. 102 0
      docker/blocks/graphite1/files/events_views.py
  68. 20 0
      docker/blocks/graphite1/files/initial_data.json
  69. 42 0
      docker/blocks/graphite1/files/local_settings.py
  70. 1 0
      docker/blocks/graphite1/files/my_htpasswd
  71. 70 0
      docker/blocks/graphite1/files/nginx.conf
  72. 8 0
      docker/blocks/graphite1/files/statsd_config.js
  73. 19 0
      docker/blocks/graphite1/files/storage-aggregation.conf
  74. 16 0
      docker/blocks/graphite1/files/storage-schemas.conf
  75. 26 0
      docker/blocks/graphite1/files/supervisord.conf
  76. 17 0
      docker/blocks/influxdb/docker-compose.yaml
  77. 0 17
      docker/blocks/influxdb/fig
  78. 6 0
      docker/blocks/jaeger/docker-compose.yaml
  79. 5 0
      docker/blocks/memcached/docker-compose.yaml
  80. 0 5
      docker/blocks/memcached/fig
  81. 14 0
      docker/blocks/mysql/docker-compose.yaml
  82. 0 9
      docker/blocks/mysql/fig
  83. 20 0
      docker/blocks/mysql_opendata/Dockerfile
  84. 9 0
      docker/blocks/mysql_opendata/docker-compose.yaml
  85. 80 0
      docker/blocks/mysql_opendata/import_csv.sql
  86. 9 0
      docker/blocks/mysql_tests/docker-compose.yaml
  87. 0 9
      docker/blocks/mysql_tests/fig
  88. 10 0
      docker/blocks/openldap/docker-compose.yaml
  89. 0 10
      docker/blocks/openldap/fig
  90. 11 0
      docker/blocks/opentsdb/docker-compose.yaml
  91. 0 11
      docker/blocks/opentsdb/fig
  92. 9 0
      docker/blocks/postgres/docker-compose.yaml
  93. 0 8
      docker/blocks/postgres/fig
  94. 7 0
      docker/blocks/postgres_tests/docker-compose.yaml
  95. 0 7
      docker/blocks/postgres_tests/fig
  96. 1 0
      docker/blocks/prometheus/Dockerfile
  97. 10 0
      docker/blocks/prometheus/alert.rules
  98. 25 0
      docker/blocks/prometheus/docker-compose.yaml
  99. 0 22
      docker/blocks/prometheus/fig
  100. 20 12
      docker/blocks/prometheus/prometheus.yml

+ 0 - 3
.bowerrc

@@ -1,3 +0,0 @@
-{
-  "directory": "public/vendor/"
-}

+ 3 - 3
.bra.toml

@@ -1,7 +1,7 @@
 [run]
 init_cmds = [
   ["go", "build", "-o", "./bin/grafana-server", "./pkg/cmd/grafana-server"],
-	["./bin/grafana-server"]
+	["./bin/grafana-server", "cfg:app_mode=development"]
 ]
 watch_all = true
 watch_dirs = [
@@ -9,9 +9,9 @@ watch_dirs = [
 	"$WORKDIR/public/views",
 	"$WORKDIR/conf",
 ]
-watch_exts = [".go", ".ini", ".toml", ".html"]
+watch_exts = [".go", ".ini", ".toml"]
 build_delay = 1500
 cmds = [
   ["go", "build", "-o", "./bin/grafana-server", "./pkg/cmd/grafana-server"],
-	["./bin/grafana-server"]
+	["./bin/grafana-server", "cfg:app_mode=development"]
 ]

+ 5 - 5
.editorconfig

@@ -1,16 +1,16 @@
 # http://editorconfig.org
 root = true
 
-[*.go]
-indent_style = tab
+[*]
+indent_style = space
 indent_size = 2
 charset = utf-8
 trim_trailing_whitespace = true
 insert_final_newline = true
 
-[*]
-indent_style = space
-indent_size = 2
+[*.go]
+indent_style = tab
+indent_size = 4
 charset = utf-8
 trim_trailing_whitespace = true
 insert_final_newline = true

+ 0 - 3
.floo

@@ -1,3 +0,0 @@
-{
-  "url": "https://floobits.com/raintank/grafana"
-}

+ 0 - 12
.flooignore

@@ -1,12 +0,0 @@
-#*
-*.o
-*.pyc
-*.pyo
-*~
-extern/
-node_modules/
-tmp/
-data/
-vendor/
-public_gen/
-dist/

+ 8 - 9
.github/ISSUE_TEMPLATE.md

@@ -1,7 +1,8 @@
-* **I'm submitting a ...**
-- [ ] Bug report
-- [ ] Feature request
-- [ ] Question / Support request: **Please do not** open a github issue. [Support Options](http://grafana.org/support/)
+Read before posting: 
+
+- Questions should be posted to https://community.grafana.com. Please search there and here on GitHub for similar issues before creating a new issue. 
+- Checkout FAQ: https://community.grafana.com/c/howto/faq
+- Checkout How to troubleshoot metric query issues: https://community.grafana.com/t/how-to-troubleshoot-metric-query-issues/50
 
 Please include this information:
 - What Grafana version are you using?
@@ -10,8 +11,6 @@ Please include this information:
 - What did you do?
 - What was the expected result?
 - What happened instead?
-
-**IMPORTANT** If it relates to metric data viz:
-- An image or text representation of your metric query
-- The raw query and response for the network request (check this in chrome dev tools network tab, here you can see metric requests and other request, please include the request body and request response)
-
+- If related to metric query / data viz:
+  - Include raw network request & response: get by opening Chrome Dev Tools (F12, Ctrl+Shift+I on windows, Cmd+Opt+I on Mac), go the network tab.
+ 

+ 3 - 1
.github/PULL_REQUEST_TEMPLATE.md

@@ -1,2 +1,4 @@
 * Link the PR to an issue for new features
-* Rebase your PR if it gets out of sync with master
+* Rebase your PR if it gets out of sync with master
+
+**REMOVE THE TEXT ABOVE BEFORE CREATING THE PULL REQUEST**

+ 17 - 2
.gitignore

@@ -4,18 +4,21 @@ coverage/
 .aws-config.json
 awsconfig
 /dist
+/public/build
+/public/views/index.html
 /emails/dist
 /public_gen
 /public/vendor/npm
 /tmp
 vendor/phantomjs/phantomjs
+vendor/phantomjs/phantomjs.exe
+profile.out
+coverage.txt
 
 docs/AWS_S3_BUCKET
 docs/GIT_BRANCH
-docs/VERSION
 docs/GITCOMMIT
 docs/changed-files
-docs/changed-files
 
 # locally required config files
 public/css/*.min.css
@@ -25,6 +28,8 @@ public/css/*.min.css
 *.swp
 .idea/
 *.iml
+*.tmp
+.DS_Store
 .vscode/
 
 /data/*
@@ -38,4 +43,14 @@ profile.cov
 .notouch
 /pkg/cmd/grafana-cli/grafana-cli
 /pkg/cmd/grafana-server/grafana-server
+/pkg/cmd/grafana-server/debug
 /examples/*/dist
+/packaging/**/*.rpm
+/packaging/**/*.deb
+
+/vendor/**/*.py
+/vendor/**/*.xml
+/vendor/**/*.yml
+/vendor/**/*_test.go
+/vendor/**/.editorconfig
+/vendor/**/appengine*

+ 0 - 10
.hooks/pre-commit

@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-test -z "$(gofmt -s -l . | grep -v vendor/src/ | tee /dev/stderr)"
-if [ $? -gt 0 ]; then
-    echo "Some files aren't formatted, please run 'go fmt ./pkg/...' to format your source code before committing"
-    exit 1
-fi
-
-
-grunt test

+ 0 - 21
.jsfmtrc

@@ -1,21 +0,0 @@
-{
-  "preset" : "default",
-
-  "lineBreak" : {
-    "before" : {
-      "VariableDeclarationWithoutInit" : 0,
-    },
-
-    "after": {
-      "AssignmentOperator": -1,
-      "ArgumentListArrayExpression": ">=1"
-    }
-  },
-
-  "whiteSpace" : {
-    "before" : {
-    },
-    "after" : {
-    }
-  }
-}

+ 1 - 1
.jshintrc

@@ -1,6 +1,6 @@
 {
   "browser": true,
-
+  "esversion": 6,
   "bitwise":false,
   "curly": true,
   "eqnull": true,

+ 500 - 4
CHANGELOG.md

@@ -1,4 +1,495 @@
-# 4.0-pre (unreleased)
+# 5.0.0 (unreleased)
+
+### WIP (in develop branch currently as its unstable or unfinished)
+- Dashboard folders
+- User groups
+- Dashboard permissions (on folder & dashboard level), permissions can be assigned to groups or individual users
+- UX changes to nav & side menu
+- New dashboard grid layout system
+
+# 4.7.0 (unreleased)
+
+## New Features
+* **Data Source Proxy**: Add support for whitelisting specified cookies that will be passed through to the data source when proxying data source requests [#5457](https://github.com/grafana/grafana/issues/5457), thanks [@robingustafsson](https://github.com/robingustafsson)
+* **Postgres/MySQL**: add __timeGroup macro for mysql [#9596](https://github.com/grafana/grafana/pull/9596), thanks [@svenklemm](https://github.com/svenklemm)
+* **Text**: Text panel are now edited in the ace editor. [#9698](https://github.com/grafana/grafana/pull/9698), thx [@mtanda](https://github.com/mtanda)
+
+## Minor
+* **Alert panel**: Adds placeholder text when no alerts are within the time range [#9624](https://github.com/grafana/grafana/issues/9624), thx [@straend](https://github.com/straend)
+
+## Tech
+* **RabbitMq**: Remove support for publishing events to RabbitMQ [#9645](https://github.com/grafana/grafana/issues/9645)
+
+## Fixes
+* **Sensu**: Send alert message to sensu output [#9551](https://github.com/grafana/grafana/issues/9551), thx [@cjchand](https://github.com/cjchand)
+* **Singlestat**: suppress error when result contains no datapoints [#9636](https://github.com/grafana/grafana/issues/9636), thx [@utkarshcmu](https://github.com/utkarshcmu)
+* **Postgres/MySQL**: Control quoting in SQL-queries when using template variables [#9030](https://github.com/grafana/grafana/issues/9030), thanks [@svenklemm](https://github.com/svenklemm)
+
+# 4.6.1 (unreleased)
+
+* **Singlestat**: Lost thresholds when using save dashboard as [#9681](https://github.com/grafana/grafana/issues/9681)
+* **Graph**: Fix for series override color picker [#9715](https://github.com/grafana/grafana/issues/9715)
+* **Go**: build using golang 1.9.2 [#9713](https://github.com/grafana/grafana/issues/9713)
+
+# 4.6.0 (2017-10-26)
+
+## Fixes
+* **Alerting**: Viewer can no longer pause alert rules [#9640](https://github.com/grafana/grafana/issues/9640)
+* **Playlist**: Bug where playlist controls was missing [#9639](https://github.com/grafana/grafana/issues/9639)
+* **Firefox**: Creating region annotations now work in firefox [#9638](https://github.com/grafana/grafana/issues/9638)
+
+# 4.6.0-beta3 (2017-10-23)
+
+## Fixes
+* **Prometheus**: Fix for browser crash for short time ranges. [#9575](https://github.com/grafana/grafana/issues/9575)
+* **Heatmap**: Fix for y-axis not showing. [#9576](https://github.com/grafana/grafana/issues/9576)
+* **Save to file**: Fix for save to file in export modal. [#9586](https://github.com/grafana/grafana/issues/9586)
+* **Postgres**: modify group by time macro so it can be used in select clause [#9527](https://github.com/grafana/grafana/pull/9527), thanks [@svenklemm](https://github.com/svenklemm)
+
+# 4.6.0-beta2 (2017-10-17)
+
+## Fixes
+* **ColorPicker**: Fix for color picker not showing [#9549](https://github.com/grafana/grafana/issues/9549)
+* **Alerting**: Fix for broken test rule button in alert tab [#9539](https://github.com/grafana/grafana/issues/9539)
+* **Cloudwatch**: Provide error message when failing to add cloudwatch datasource [#9534](https://github.com/grafana/grafana/pull/9534), thx [@mtanda](https://github.com/mtanda)
+* **Cloudwatch**: Fix unused period parameter [#9536](https://github.com/grafana/grafana/pull/9536), thx [@mtanda](https://github.com/mtanda)
+* **CSV Export**: Fix for broken CSV export [#9525](https://github.com/grafana/grafana/issues/9525)
+* **Text panel**: Fix for issue with break lines in Firefox [#9491](https://github.com/grafana/grafana/issues/9491)
+* **Annotations**: Fix for issue saving annotation event in MySQL DB [#9550](https://github.com/grafana/grafana/issues/9550), thanks [@krise3k](https://github.com/krise3k)
+
+
+# 4.6.0-beta1 (2017-10-13)
+
+## New Features
+* **Annotations**: Add support for creating annotations from graph panel [#8197](https://github.com/grafana/grafana/pull/8197)
+* **GCS**: Adds support for Google Cloud Storage [#8370](https://github.com/grafana/grafana/issues/8370) thx [@chuhlomin](https://github.com/chuhlomin)
+* **Prometheus**: Adds /metrics endpoint for exposing Grafana metrics. [#9187](https://github.com/grafana/grafana/pull/9187)
+* **Graph**: Add support for local formating in axis. [#1395](https://github.com/grafana/grafana/issues/1395), thx [@m0nhawk](https://github.com/m0nhawk)
+* **Jaeger**: Add support for open tracing using jaeger in Grafana. [#9213](https://github.com/grafana/grafana/pull/9213)
+* **Unit types**: New date & time unit types added, useful in singlestat to show dates & times. [#3678](https://github.com/grafana/grafana/issues/3678), [#6710](https://github.com/grafana/grafana/issues/6710), [#2764](https://github.com/grafana/grafana/issues/2764)
+* **CLI**: Make it possible to install plugins from any url [#5873](https://github.com/grafana/grafana/issues/5873)
+* **Prometheus**: Add support for instant queries [#5765](https://github.com/grafana/grafana/issues/5765), thx [@mtanda](https://github.com/mtanda)
+* **Cloudwatch**: Add support for alerting using the cloudwatch datasource [#8050](https://github.com/grafana/grafana/pull/8050), thx [@mtanda](https://github.com/mtanda)
+* **Pagerduty**: Include triggering series in pagerduty notification [#8479](https://github.com/grafana/grafana/issues/8479), thx [@rickymoorhouse](https://github.com/rickymoorhouse)
+* **Timezone**: Time ranges like Today & Yesterday now work correctly when timezone setting is set to UTC [#8916](https://github.com/grafana/grafana/issues/8916), thx [@ctide](https://github.com/ctide)
+* **Prometheus**: Align $__interval with the step parameters. [#9226](https://github.com/grafana/grafana/pull/9226), thx [@alin-amana](https://github.com/alin-amana)
+* **Prometheus**: Autocomplete for label name and label value [#9208](https://github.com/grafana/grafana/pull/9208), thx [@mtanda](https://github.com/mtanda)
+* **Postgres**: New Postgres data source [#9209](https://github.com/grafana/grafana/pull/9209), thx [@svenklemm](https://github.com/svenklemm)
+* **Datasources**: Make datasource HTTP requests verify TLS by default. closes [#9371](https://github.com/grafana/grafana/issues/9371), [#5334](https://github.com/grafana/grafana/issues/5334), [#8812](https://github.com/grafana/grafana/issues/8812), thx [@mattbostock](https://github.com/mattbostock)
+* **OAuth**: Verify TLS during OAuth callback [#9373](https://github.com/grafana/grafana/issues/9373), thx [@mattbostock](https://github.com/mattbostock)
+
+## Minor
+* **SMTP**: Make it possible to set specific HELO for smtp client. [#9319](https://github.com/grafana/grafana/issues/9319)
+* **Dataproxy**: Allow grafana to renegotiate tls connection [#9250](https://github.com/grafana/grafana/issues/9250)
+* **HTTP**: set net.Dialer.DualStack to true for all http clients [#9367](https://github.com/grafana/grafana/pull/9367)
+* **Alerting**: Add diff and percent diff as series reducers [#9386](https://github.com/grafana/grafana/pull/9386), thx [@shanhuhai5739](https://github.com/shanhuhai5739)
+* **Slack**: Allow images to be uploaded to slack when Token is present [#7175](https://github.com/grafana/grafana/issues/7175), thx [@xginn8](https://github.com/xginn8)
+* **Opsgenie**: Use their latest API instead of old version [#9399](https://github.com/grafana/grafana/pull/9399), thx [@cglrkn](https://github.com/cglrkn)
+* **Table**: Add support for displaying the timestamp with milliseconds [#9429](https://github.com/grafana/grafana/pull/9429), thx [@s1061123](https://github.com/s1061123)
+* **Hipchat**: Add metrics, message and image to hipchat notifications [#9110](https://github.com/grafana/grafana/issues/9110), thx [@eloo](https://github.com/eloo)
+* **Kafka**: Add support for sending alert notifications to kafka [#7104](https://github.com/grafana/grafana/issues/7104), thx [@utkarshcmu](https://github.com/utkarshcmu)
+* **Alerting**: add count_non_null as series reducer [#9516](https://github.com/grafana/grafana/issues/9516)
+
+## Tech
+* **Go**: Grafana is now built using golang 1.9
+* **Webpack**: Changed from systemjs to webpack (see readme or building from source guide for new build instructions). Systemjs is still used to load plugins but now plugins can only import a limited set of dependencies. See [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) for more details on how this can effect some plugins.
+
+# 4.5.2 (2017-09-22)
+
+## Fixes
+* **Graphite**: Fix for issues with jsonData & graphiteVersion null errors [#9258](https://github.com/grafana/grafana/issues/9258)
+* **Graphite**: Fix for Grafana internal metrics to Graphite sending NaN values [#9279](https://github.com/grafana/grafana/issues/9279)
+* **HTTP API**: Fix for HEAD method requests [#9307](https://github.com/grafana/grafana/issues/9307)
+* **Templating**: Fix for duplicate template variable queries when refresh is set to time range change [#9185](https://github.com/grafana/grafana/issues/9185)
+* **Metrics**: dont write NaN values to graphite [#9279](https://github.com/grafana/grafana/issues/9279)
+
+# 4.5.1 (2017-09-15)
+
+## Fixes
+* **MySQL**: Fixed issue with query editor not showing [#9247](https://github.com/grafana/grafana/issues/9247)
+
+## Breaking changes
+* **Metrics**: The metric structure for internal metrics about Grafana published to graphite has changed. This might break dashboards for internal metrics.
+
+# 4.5.0 (2017-09-14)
+
+## Fixes & Enhancements since beta1
+* **Security**: Security fix for api vulnerability (in multiple org setups).
+* **Shortcuts**: Adds shortcut for creating new dashboard [#8876](https://github.com/grafana/grafana/pull/8876) thx [@mtanda](https://github.com/mtanda)
+* **Graph**: Right Y-Axis label position fixed [#9172](https://github.com/grafana/grafana/pull/9172)
+* **General**: Improve rounding of time intervals [#9197](https://github.com/grafana/grafana/pull/9197), thx [@alin-amana](https://github.com/alin-amana)
+
+# 4.5.0-beta1 (2017-09-05)
+
+## New Features
+
+* **Table panel**: Render cell values as links that can have an url template that uses variables from current table row. [#3754](https://github.com/grafana/grafana/issues/3754)
+* **Elasticsearch**: Add ad hoc filters directly by clicking values in table panel [#8052](https://github.com/grafana/grafana/issues/8052).
+* **MySQL**: New rich query editor with syntax highlighting
+* **Prometheus**: New rich query editor with syntax highlighting, metric & range auto complete and integrated function docs. [#5117](https://github.com/grafana/grafana/issues/5117)
+
+## Enhancements
+
+* **GitHub OAuth**: Support for GitHub organizations with 100+ teams. [#8846](https://github.com/grafana/grafana/issues/8846), thx [@skwashd](https://github.com/skwashd)
+* **Graphite**: Calls to Graphite api /metrics/find now include panel or dashboad time range (from & until) in most cases, [#8055](https://github.com/grafana/grafana/issues/8055)
+* **Graphite**: Added new graphite 1.0 functions, available if you set version to 1.0.x in data source settings. New Functions: mapSeries, reduceSeries, isNonNull, groupByNodes, offsetToZero, grep, weightedAverage, removeEmptySeries, aggregateLine, averageOutsidePercentile, delay, exponentialMovingAverage, fallbackSeries, integralByInterval, interpolate, invert, linearRegression, movingMin, movingMax, movingSum, multiplySeriesWithWildcards, pow, powSeries, removeBetweenPercentile, squareRoot, timeSlice, closes [#8261](https://github.com/grafana/grafana/issues/8261)
+- **Elasticsearch**: Ad-hoc filters now use query phrase match filters instead of term filters, works on non keyword/raw fields [#9095](https://github.com/grafana/grafana/issues/9095).
+
+### Breaking change
+
+* **InfluxDB/Elasticsearch**: The panel & data source option named "Group by time interval" is now named "Min time interval" and does now always define a lower limit for the auto group by time. Without having to use `>` prefix (that prefix still works). This should in theory have close to zero actual impact on existing dashboards. It does mean that if you used this setting to define a hard group by time interval of, say "1d", if you zoomed to a time range wide enough the time range could increase above the "1d" range as the setting is now always considered a lower limit.
+* **Elasticsearch**: Elasticsearch metric queries without date histogram now return table formated data making table panel much easier to use for this use case. Should not break/change existing dashboards with stock panels but external panel plugins can be affected.
+
+## Changes
+
+* **InfluxDB**: Change time range filter for absolute time ranges to be inclusive instead of exclusive [#8319](https://github.com/grafana/grafana/issues/8319), thx [@Oxydros](https://github.com/Oxydros)
+* **InfluxDB**: Added paranthesis around tag filters in queries [#9131](https://github.com/grafana/grafana/pull/9131)
+
+## Bug Fixes
+
+* **Modals**: Maintain scroll position after opening/leaving modal [#8800](https://github.com/grafana/grafana/issues/8800)
+* **Templating**: You cannot select data source variables as data source for other template variables [#7510](https://github.com/grafana/grafana/issues/7510)
+* **MySQL/Postgres**: Fix for max_idle_conn option default which was wrongly set to zero which does not mean unlimited but means zero, which in practice kind of disables connection pooling, which is not good. Fixes [#8513](https://github.com/grafana/grafana/issues/8513)
+
+# 4.4.3 (2017-08-07)
+
+## Bug Fixes
+
+* **Search**: Fix for issue that casued search view to hide  when you clicked starred or tags filters, fixes [#8981](https://github.com/grafana/grafana/issues/8981)
+* **Modals**: ESC key now closes modal again, fixes [#8981](https://github.com/grafana/grafana/issues/8988), thx [@j-white](https://github.com/j-white)
+
+# 4.4.2 (2017-08-01)
+
+## Bug Fixes
+
+* **GrafanaDB(mysql)**: Fix for dashboard_version.data column type, now changed to MEDIUMTEXT, fixes [#8813](https://github.com/grafana/grafana/issues/8813)
+* **Dashboard(settings)**: Closing setting views using ESC key did not update url correctly, fixes [#8869](https://github.com/grafana/grafana/issues/8869)
+* **InfluxDB**: Wrong username/password parameter name when using direct access, fixes [#8789](https://github.com/grafana/grafana/issues/8789)
+* **Forms(TextArea)**: Bug fix for no scroll in text areas [#8797](https://github.com/grafana/grafana/issues/8797)
+* **Png Render API**: Bug fix for timeout url parameter. It now works as it should. Default value was also increased from 30 to 60 seconds [#8710](https://github.com/grafana/grafana/issues/8710)
+* **Search**: Fix for not being able to close search by clicking on right side of search result container, [8848](https://github.com/grafana/grafana/issues/8848)
+* **Cloudwatch**: Fix for using variables in templating metrics() query, [8965](https://github.com/grafana/grafana/issues/8965)
+
+## Changes
+
+* **Settings(defaults)**: allow_sign_up default changed from true to false [#8743](https://github.com/grafana/grafana/issues/8743)
+* **Settings(defaults)**: allow_org_create default changed from true to false
+
+# 4.4.1 (2017-07-05)
+
+## Bug Fixes
+
+* **Migrations**: migration fails where dashboard.created_by is null [#8783](https://github.com/grafana/grafana/issues/8783)
+
+# 4.4.0 (2017-07-04)
+
+## New Features
+**Dashboard History**: View dashboard version history, compare any two versions (summary & json diffs), restore to old version. This big feature
+was contributed by **Walmart Labs**. Big thanks to them for this massive contribution!
+Initial feature request: [#4638](https://github.com/grafana/grafana/issues/4638)
+Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472)
+
+## Enhancements
+* **Elasticsearch**: Added filter aggregation label [#8420](https://github.com/grafana/grafana/pull/8420), thx [@tianzk](github.com/tianzk)
+* **Sensu**: Added option for source and handler [#8405](https://github.com/grafana/grafana/pull/8405), thx [@joemiller](github.com/joemiller)
+* **CSV**: Configurable csv export datetime format [#8058](https://github.com/grafana/grafana/issues/8058), thx [@cederigo](github.com/cederigo)
+* **Table Panel**: Column style that preserves formatting/indentation (like pre tag) [#6617](https://github.com/grafana/grafana/issues/6617)
+* **DingDing**: Add DingDing Alert Notifier [#8473](https://github.com/grafana/grafana/pull/8473) thx [@jiamliang](https://github.com/jiamliang)
+
+## Minor Enhancements
+
+* **Elasticsearch**: Add option for result set size in raw_document [#3426](https://github.com/grafana/grafana/issues/3426) [#8527](https://github.com/grafana/grafana/pull/8527), thx [@mk-dhia](github.com/mk-dhia)
+
+## Bug Fixes
+
+* **Graph**: Bug fix for negative values in histogram mode [#8628](https://github.com/grafana/grafana/issues/8628)
+
+# 4.3.2 (2017-05-31)
+
+## Bug fixes
+
+* **InfluxDB**: Fixed issue with query editor not showing ALIAS BY input field when in text editor mode [#8459](https://github.com/grafana/grafana/issues/8459)
+* **Graph Log Scale**: Fixed issue with log scale going below x-axis [#8244](https://github.com/grafana/grafana/issues/8244)
+* **Playlist**: Fixed dashboard play order issue [#7688](https://github.com/grafana/grafana/issues/7688)
+* **Elasticsearch**: Fixed table query issue with ES 2.x [#8467](https://github.com/grafana/grafana/issues/8467), thx [@goldeelox](https://github.com/goldeelox)
+
+## Changes
+* **Lazy Loading Of Panels**: Panels are no longer loaded as they are scrolled into view, this was reverted due to Chrome bug, might be reintroduced when Chrome fixes it's JS blocking behavior on scroll. [#8500](https://github.com/grafana/grafana/issues/8500)
+
+# 4.3.1 (2017-05-23)
+
+## Bug fixes
+
+* **S3 image upload**: Fixed image url issue for us-east-1 (us standard) region. If you were missing slack images for alert notifications this should fix it. [#8444](https://github.com/grafana/grafana/issues/8444)
+
+# 4.3.0-stable (2017-05-23)
+
+## Bug fixes
+
+* **Gzip**: Fixed crash when gzip was enabled [#8380](https://github.com/grafana/grafana/issues/8380)
+* **Graphite**: Fixed issue with Toggle edit mode did in query editor [#8377](https://github.com/grafana/grafana/issues/8377)
+* **Alerting**: Fixed issue with state history not showing query execution errors [#8412](https://github.com/grafana/grafana/issues/8412)
+* **Alerting**: Fixed issue with missing state history events/annotations when using sqlite3 database [#7992](https://github.com/grafana/grafana/issues/7992)
+* **Sqlite**: Fixed with database table locked and using sqlite3 database [#7992](https://github.com/grafana/grafana/issues/7992)
+* **Alerting**: Fixed issue with annotations showing up in unsaved dashboards, new graph & alert panel. [#8361](https://github.com/grafana/grafana/issues/8361)
+* **webdav**: Fixed http proxy env variable support for webdav image upload [#7922](https://github.com/grafana/grafana/issues/79222), thx [@berghauz](https://github.com/berghauz)
+* **Prometheus**: Fixed issue with hiding query [#8413](https://github.com/grafana/grafana/issues/8413)
+
+## Enhancements
+
+* **VictorOps**:  Now supports panel image & auto resolve [#8431](https://github.com/grafana/grafana/pull/8431), thx [@davidmscott](https://github.com/davidmscott)
+* **Alerting**:  Alert annotations now provide more info [#8421](https://github.com/grafana/grafana/pull/8421)
+
+# 4.3.0-beta1 (2017-05-12)
+
+## Enhancements
+
+* **InfluxDB**: influxdb query builder support for ORDER BY and LIMIT (allows TOPN queries) [#6065](https://github.com/grafana/grafana/issues/6065) Support influxdb's SLIMIT Feature [#7232](https://github.com/grafana/grafana/issues/7232) thx [@thuck](https://github.com/thuck)
+* **Panels**: Delay loading & Lazy load panels as they become visible (scrolled into view) [#5216](https://github.com/grafana/grafana/issues/5216) thx [@jifwin](https://github.com/jifwin)
+* **Graph**: Support auto grid min/max when using log scale [#3090](https://github.com/grafana/grafana/issues/3090), thx [@bigbenhur](https://github.com/bigbenhur)
+* **Graph**: Support for histograms [#600](https://github.com/grafana/grafana/issues/600)
+* **Prometheus**: Support table response formats (column per label) [#6140](https://github.com/grafana/grafana/issues/6140), thx [@mtanda](https://github.com/mtanda)
+* **Single Stat Panel**: support for non time series data [#6564](https://github.com/grafana/grafana/issues/6564)
+* **Server**: Monitoring Grafana (health check endpoint) [#3302](https://github.com/grafana/grafana/issues/3302)
+* **Heatmap**: Heatmap Panel [#7934](https://github.com/grafana/grafana/pull/7934)
+* **Elasticsearch**: histogram aggregation [#3164](https://github.com/grafana/grafana/issues/3164)
+
+## Minor Enhancements
+
+* **InfluxDB**: Small fix for the "glow" when focus the field for LIMIT and SLIMIT [#7799](https://github.com/grafana/grafana/pull/7799) thx [@thuck](https://github.com/thuck)
+* **Prometheus**: Make Prometheus query field a textarea [#7663](https://github.com/grafana/grafana/issues/7663), thx [@hagen1778](https://github.com/hagen1778)
+* **Prometheus**: Step parameter changed semantics to min step to reduce the load on Prometheus and rendering in browser [#8073](https://github.com/grafana/grafana/pull/8073), thx [@bobrik](https://github.com/bobrik)
+* **Templating**: Should not be possible to create self-referencing (recursive) template variable definitions [#7614](https://github.com/grafana/grafana/issues/7614) thx [@thuck](https://github.com/thuck)
+* **Cloudwatch**: Correctly obtain IAM roles within ECS container tasks [#7892](https://github.com/grafana/grafana/issues/7892) thx [@gomlgs](https://github.com/gomlgs)
+* **Units**: New number format: Scientific notation [#7781](https://github.com/grafana/grafana/issues/7781) thx [@cadnce](https://github.com/cadnce)
+* **Oauth**: Add common type for oauth authorization errors [#6428](https://github.com/grafana/grafana/issues/6428) thx [@amenzhinsky](https://github.com/amenzhinsky)
+* **Templating**: Data source variable now supports multi value and panel repeats [#7030](https://github.com/grafana/grafana/issues/7030) thx [@mtanda](https://github.com/mtanda)
+* **Telegram**: Telegram alert is not sending metric and legend. [#8110](https://github.com/grafana/grafana/issues/8110), thx [@bashgeek](https://github.com/bashgeek)
+* **Graph**: Support dashed lines [#514](https://github.com/grafana/grafana/issues/514), thx [@smalik03](https://github.com/smalik03)
+* **Table**: Support to change column header text [#3551](https://github.com/grafana/grafana/issues/3551)
+* **Alerting**: Better error when SMTP is not configured [#8093](https://github.com/grafana/grafana/issues/8093)
+* **Pushover**: Add an option to attach graph image link in Pushover notification [#8043](https://github.com/grafana/grafana/issues/8043) thx [@devkid](https://github.com/devkid)
+* **WebDAV**: Allow to set different ImageBaseUrl for WebDAV upload and image link [#7914](https://github.com/grafana/grafana/issues/7914)
+* **Panels**: type-ahead mixed datasource selection [#7697](https://github.com/grafana/grafana/issues/7697) thx [@mtanda](https://github.com/mtanda)
+* **Security**:User enumeration problem [#7619](https://github.com/grafana/grafana/issues/7619)
+* **InfluxDB**: Register new queries available in InfluxDB - Holt Winters [#5619](https://github.com/grafana/grafana/issues/5619) thx [@rikkuness](https://github.com/rikkuness)
+* **Server**: Support listening on a UNIX socket [#4030](https://github.com/grafana/grafana/issues/4030), thx [@mitjaziv](https://github.com/mitjaziv)
+* **Graph**: Support log scaling for values smaller 1 [#5278](https://github.com/grafana/grafana/issues/5278)
+* **InfluxDB**: Slow 'select measurement' rendering for InfluxDB [#2524](https://github.com/grafana/grafana/issues/2524), thx [@sbhenderson](https://github.com/sbhenderson)
+* **Config**: Configurable signout menu activation [#7968](https://github.com/grafana/grafana/pull/7968), thx [@seuf](https://github.com/seuf)
+
+## Fixes
+* **Table Panel**: Fixed annotation display in table panel, [#8023](https://github.com/grafana/grafana/issues/8023)
+* **Dashboard**: If refresh is blocked due to tab not visible, then refresh when it becomes visible [#8076](https://github.com/grafana/grafana/issues/8076) thanks [@SimenB](https://github.com/SimenB)
+* **Snapshots**: Fixed problem with annotations & snapshots [#7659](https://github.com/grafana/grafana/issues/7659)
+* **Graph**: MetricSegment loses type when value is an asterisk [#8277](https://github.com/grafana/grafana/issues/8277), thx [@Gordiychuk](https://github.com/Gordiychuk)
+* **Alerting**: Alert notifications do not show charts when using a non public S3 bucket [#8250](https://github.com/grafana/grafana/issues/8250) thx [@rogerswingle](https://github.com/rogerswingle)
+* **Graph**: 100% client CPU usage on red alert glow animation [#8222](https://github.com/grafana/grafana/issues/8222)
+* **InfluxDB**: Templating: "All" query does match too much [#8165](https://github.com/grafana/grafana/issues/8165)
+* **Dashboard**: Description tooltip is not fully displayed [#7970](https://github.com/grafana/grafana/issues/7970)
+* **Proxy**: Redirect after switching Org does not obey sub path in root_url (using reverse proxy) [#8089](https://github.com/grafana/grafana/issues/8089)
+* **Templating**: Restoration of ad-hoc variable from URL does not work correctly [#8056](https://github.com/grafana/grafana/issues/8056) thx [@tamayika](https://github.com/tamayika)
+* **InfluxDB**: timeFilter cannot be used twice in alerts [#7969](https://github.com/grafana/grafana/issues/7969)
+* **MySQL**: 4-byte UTF8 not supported when using MySQL database (allows Emojis) [#7958](https://github.com/grafana/grafana/issues/7958)
+* **Alerting**: api/alerts and api/alert/:id hold previous data for "message" and "Message" field when field value is changed from "some string" to empty string. [#7927](https://github.com/grafana/grafana/issues/7927)
+* **Graph**: Cannot add fill below to series override [#7916](https://github.com/grafana/grafana/issues/7916)
+* **InfluxDB**: Influxb Datasource test passes even if the Database doesn't exist [#7864](https://github.com/grafana/grafana/issues/7864)
+* **Prometheus**: Displaying Prometheus annotations is incredibly slow [#7750](https://github.com/grafana/grafana/issues/7750), thx [@mtanda](https://github.com/mtanda)
+* **Graphite**: grafana generates empty find query to graphite -> 422 Unprocessable Entity [#7740](https://github.com/grafana/grafana/issues/7740)
+* **Admin**: make organisation filter case insensitive [#8194](https://github.com/grafana/grafana/issues/8194), thx [@Alexander-N](https://github.com/Alexander-N)
+
+## Changes
+* **Elasticsearch**: Changed elasticsearch Terms aggregation to default to Min Doc Count to 1, and sort order to Top [#8321](https://github.com/grafana/grafana/issues/8321)
+
+## Tech
+
+* **Library Upgrade**: inconshreveable/log15 outdated - no support for solaris [#8262](https://github.com/grafana/grafana/issues/8262)
+* **Library Upgrade**: Upgrade Macaron [#7600](https://github.com/grafana/grafana/issues/7600)
+
+# 4.2.0 (2017-03-22)
+## Minor Enhancements
+* **Templates**: Prevent use of the prefix `__` for templates in web UI [#7678](https://github.com/grafana/grafana/issues/7678)
+* **Threema**: Add emoji to Threema alert notifications [#7676](https://github.com/grafana/grafana/pull/7676) thx [@dbrgn](https://github.com/dbrgn)
+* **Panels**: Support dm3 unit [#7695](https://github.com/grafana/grafana/issues/7695) thx [@mitjaziv](https://github.com/mitjaziv)
+* **Docs**: Added some details about Sessions in Postgres [#7694](https://github.com/grafana/grafana/pull/7694) thx [@rickard-von-essen](https://github.com/rickard-von-essen)
+* **Influxdb**: Allow commas in template variables [#7681](https://github.com/grafana/grafana/issues/7681) thx [@thuck](https://github.com/thuck)
+* **Cloudwatch**: stop using deprecated session.New() [#7736](https://github.com/grafana/grafana/issues/7736) thx [@mtanda](https://github.com/mtanda)
+* **OpenTSDB**: Pass dropcounter rate option if no max counter and no reset value or reset value as 0 is specified [#7743](https://github.com/grafana/grafana/pull/7743) thx [@r4um](https://github.com/r4um)
+* **Templating**: support full resolution for $interval variable [#7696](https://github.com/grafana/grafana/pull/7696) thx [@mtanda](https://github.com/mtanda)
+* **Elasticsearch**: Unique Count on string fields in ElasticSearch [#3536](https://github.com/grafana/grafana/issues/3536), thx [@pyro2927](https://github.com/pyro2927)
+* **Templating**: Data source template variable that refers to other variable in regex filter [#6365](https://github.com/grafana/grafana/issues/6365) thx [@rlodge](https://github.com/rlodge)
+* **Admin**: Global User List: add search and pagination [#7469](https://github.com/grafana/grafana/issues/7469)
+* **User Management**: Invite UI is now disabled when login form is disabled [#7875](https://github.com/grafana/grafana/issues/7875)
+
+## Bugfixes
+* **Webhook**: Use proxy settings from environment variables [#7710](https://github.com/grafana/grafana/issues/7710)
+* **Panels**: Deleting a dashboard with unsaved changes raises an error message [#7591](https://github.com/grafana/grafana/issues/7591) thx [@thuck](https://github.com/thuck)
+* **Influxdb**: Query builder detects regex to easily for measurement [#7276](https://github.com/grafana/grafana/issues/7276) thx [@thuck](https://github.com/thuck)
+* **Docs**: router_logging not documented [#7723](https://github.com/grafana/grafana/issues/7723)
+* **Alerting**: Spelling mistake [#7739](https://github.com/grafana/grafana/pull/7739) thx [@woutersmit](https://github.com/woutersmit)
+* **Alerting**: Graph legend scrolls to top when an alias is toggled/clicked [#7680](https://github.com/grafana/grafana/issues/7680) thx [@p4ddy1](https://github.com/p4ddy1)
+* **Panels**: Fixed panel tooltip description after scrolling down [#7708](https://github.com/grafana/grafana/issues/7708) thx [@askomorokhov](https://github.com/askomorokhov)
+
+# 4.2.0-beta1 (2017-02-27)
+
+## Enhancements
+* **Telegram**: Added Telegram alert notifier [#7098](https://github.com/grafana/grafana/pull/7098), thx [@leonoff](https://github.com/leonoff)
+* **Templating**: Make $__interval and $__interval_ms global built in variables that can be used in by any datasource (in panel queries), closes [#7190](https://github.com/grafana/grafana/issues/7190), closes [#6582](https://github.com/grafana/grafana/issues/6582)
+* **S3 Image Store**: External s3 image store (used in alert notifications) now support AWS IAM Roles, closes [#6985](https://github.com/grafana/grafana/issues/6985), [#7058](https://github.com/grafana/grafana/issues/7058) thx [@mtanda](https://github.com/mtanda)
+* **SingleStat**: Implements diff aggregation method for singlestat [#7234](https://github.com/grafana/grafana/issues/7234), thx [@oliverpool](https://github.com/oliverpool)
+* **Dataproxy**: Added setting to enable more verbose logging in dataproxy [#7209](https://github.com/grafana/grafana/pull/7209), thx [@Ricky-N](https://github.com/Ricky-N)
+* **Alerting**: Better information about why an alert triggered [#7035](https://github.com/grafana/grafana/issues/7035)
+* **LINE**: Add LINE as alerting notification channel [#7301](https://github.com/grafana/grafana/pull/7301), thx [@huydx](https://github.com/huydx)
+* **LINE**: Adds image to notification message [#7417](https://github.com/grafana/grafana/pull/7417), thx [@Erliz](https://github.com/Erliz)
+* **Hipchat**: Adds support for sending alert notifications to hipchat [#6451](https://github.com/grafana/grafana/issues/6451), thx [@jregovic](https://github.com/jregovic)
+* **Alerting**: Uploading images for alert notifications is now optional [#7419](https://github.com/grafana/grafana/issues/7419)
+* **Dashboard**: Adds shortcut for collapsing/expanding all rows [#552](https://github.com/grafana/grafana/issues/552), thx [@mtanda](https://github.com/mtanda)
+* **Alerting**: Adds de duping of alert notifications [#7632](https://github.com/grafana/grafana/pull/7632)
+* **Orgs**: Sharing dashboards using Grafana share feature will now redirect to correct org. [#1613](https://github.com/grafana/grafana/issues/1613)
+* **Pushover**: Add Pushover alert notifications [#7526](https://github.com/grafana/grafana/pull/7526) thx [@devkid](https://github.com/devkid)
+* **Threema**: Add Threema Gateway alert notification integration [#7482](https://github.com/grafana/grafana/pull/7482) thx [@dbrgn](https://github.com/dbrgn)
+
+## Minor Enhancements
+* **Optimzation**: Never issue refresh event when Grafana tab is not visible [#7218](https://github.com/grafana/grafana/issues/7218), thx [@mtanda](https://github.com/mtanda)
+* **Browser History**: Browser back/forward now works time ranges / zoom, [#7259](https://github.com/grafana/grafana/issues/7259)
+* **Elasticsearch**: Support for Min Doc Count options in Terms aggregation [#7324](https://github.com/grafana/grafana/pull/7324), thx [@lpic10](https://github.com/lpic10)
+* **Elasticsearch**: Term aggregation limit can now be changed in template queries [#7112](https://github.com/grafana/grafana/issues/7112), thx [@FFalcon](https://github.com/FFalcon)
+* **Elasticsearch**: Ad-hoc filters now support all operators [#7612](https://github.com/grafana/grafana/issues/7612), thx [@tamayika](https://github.com/tamayika)
+* **Graph**: Add full series name as title for legends. [#7493](https://github.com/grafana/grafana/pull/7493), thx [@kolobaev](https://github.com/kolobaev)
+* **Table**: Add a message when queries returns no data. [#6109](https://github.com/grafana/grafana/issues/6109), thx [@xginn8](https://github.com/xginn8)
+* **Graph**: Set max width for series names in legend tables. [#2385](https://github.com/grafana/grafana/issues/2385), thx [@kolobaev](https://github.com/kolobaev)
+* **Database**: Allow max db connection pool configuration [#7427](https://github.com/grafana/grafana/issues/7427), thx [@huydx](https://github.com/huydx)
+* **Datasources** Delete datsource by name [#7476](https://github.com/grafana/grafana/issues/7476), thx [@huydx](https://github.com/huydx)
+* **Dataproxy**: Only allow get that begins with api/ to access Prometheus [#7459](https://github.com/grafana/grafana/pull/7459), thx [@mtanda](https://github.com/mtanda)
+* **Snapshot**: Make timeout for snapshot creation configurable [#7449](https://github.com/grafana/grafana/pull/7449) thx [@ryu1-sakai](https://github.com/ryu1-sakai)
+* **Panels**: Add more physics units [#7554](https://github.com/grafana/grafana/pull/7554) thx [@ryantxu](https://github.com/ryantxu)
+* **Email**: Add sender's name on email [#2131](https://github.com/grafana/grafana/issues/2131) thx [@jacobbednarz](https://github.com/jacobbednarz)
+* **HTTPS**: Set tls 1.2 as lowest tls version. [#7347](https://github.com/grafana/grafana/pull/7347) thx [@roman-vynar](https://github.com/roman-vynar)
+* **Table**: Added suppressing of empty results to table plugin. [#7602](https://github.com/grafana/grafana/pull/7602) thx [@LLIyRiK](https://github.com/LLIyRiK)
+
+## Tech
+
+* **Library Upgrade**: Upgraded angularjs from 1.5.8 to 1.6.1 [#7274](https://github.com/grafana/grafana/issues/7274)
+* **Backend**: Grafana is now built using golang 1.8
+
+## Bugfixes
+* **Alerting**: Fixes missing support for no_data and execution error when testing alerts [#7149](https://github.com/grafana/grafana/issues/7149)
+* **Dashboard**: Avoid duplicate data in dashboard json for panels with alerts [#7256](https://github.com/grafana/grafana/pull/7256)
+* **Alertlist**: Only show scrollbar when required [#7269](https://github.com/grafana/grafana/issues/7269)
+* **SMTP**: Set LocalName to hostname [#7223](https://github.com/grafana/grafana/issues/7223)
+* **Sidemenu**: Disable sign out in sidemenu for AuthProxyEnabled [#7377](https://github.com/grafana/grafana/pull/7377), thx [@solugebefola](https://github.com/solugebefola)
+* **Prometheus**: Add support for basic auth in Prometheus tsdb package [#6799](https://github.com/grafana/grafana/issues/6799), thx [@hagen1778](https://github.com/hagen1778)
+* **OAuth**: Redirect to original page when logging in with OAuth [#7513](https://github.com/grafana/grafana/issues/7513)
+* **Annotations**: Wrap text in annotations tooltip [#7542](https://github.com/grafana/grafana/pull/7542), thx [@xginn8](https://github.com/xginn8)
+* **Templating**: Fixes error when using numeric sort on empty strings [#7382](https://github.com/grafana/grafana/issues/7382)
+* **Templating**: Fixed issue detecting template variable dependency [#7354](https://github.com/grafana/grafana/issues/7354)
+
+# 4.1.2 (2017-02-13)
+
+### Bugfixes
+* **Table**: Fixes broken annotation rendering mode in the table panel [#7268](https://github.com/grafana/grafana/issues/7268)
+* **Data Sources**: Sorting for lists of data sources in UI is now case insensitive [#7491](https://github.com/grafana/grafana/issues/7491)
+* **Admin**: Support more then 1000 users in global users list [#7469](https://github.com/grafana/grafana/issues/7469)
+
+# 4.1.1 (2017-01-11)
+
+### Bugfixes
+* **Graph Panel**: Fixed issue with legend height in table mode [#7221](https://github.com/grafana/grafana/issues/7221)
+
+# 4.1.0 (2017-01-11)
+
+### Bugfixes
+* **Server side PNG rendering**: Fixed issue with y-axis label rotation in phantomjs rendered images [#6924](https://github.com/grafana/grafana/issues/6924)
+* **Graph**: Fixed centering of y-axis label [#7099](https://github.com/grafana/grafana/issues/7099)
+* **Graph**: Fixed graph legend table mode and always visible scrollbar [#6828](https://github.com/grafana/grafana/issues/6828)
+* **Templating**: Fixed template variable value groups/tags feature [#6752](https://github.com/grafana/grafana/issues/6752)
+* **Webhook**: Fixed webhook username mismatch [#7195](https://github.com/grafana/grafana/pull/7195), thx [@theisenmark](https://github.com/theisenmark)
+* **Influxdb**: Handles time(auto) the same way as time($interval) [#6997](https://github.com/grafana/grafana/issues/6997)
+
+## Enhancements
+* **Elasticsearch**: Added support for all moving average options [#7154](https://github.com/grafana/grafana/pull/7154), thx [@vaibhavinbayarea](https://github.com/vaibhavinbayarea)
+
+# 4.1-beta1 (2016-12-21)
+
+### Enhancements
+* **Postgres**: Add support for Certs for Postgres database [#6655](https://github.com/grafana/grafana/issues/6655)
+* **Victorops**: Add VictorOps notification integration [#6411](https://github.com/grafana/grafana/issues/6411), thx [@ichekrygin](https://github.com/ichekrygin)
+* **Opsgenie**: Add OpsGenie notification integratiion [#6687](https://github.com/grafana/grafana/issues/6687), thx [@kylemcc](https://github.com/kylemcc)
+* **Singlestat**: New aggregation on singlestat panel [#6740](https://github.com/grafana/grafana/pull/6740), thx [@dirk-leroux](https://github.com/dirk-leroux)
+* **Cloudwatch**: Make it possible to specify access and secret key on the data source config page [#6697](https://github.com/grafana/grafana/issues/6697)
+* **Table**: Added Hidden Column Style for Table Panel [#5677](https://github.com/grafana/grafana/pull/5677), thx [@bmundt](https://github.com/bmundt)
+* **Graph**: Shared crosshair option renamed to shared tooltip, shows tooltip on all graphs as you hover over one graph. [#1578](https://github.com/grafana/grafana/pull/1578), [#6274](https://github.com/grafana/grafana/pull/6274)
+* **Elasticsearch**: Added support for Missing option (bucket) for terms aggregation [#4244](https://github.com/grafana/grafana/pull/4244), thx [@shanielh](https://github.com/shanielh)
+* **Elasticsearch**: Added support for Elasticsearch 5.x [#5740](https://github.com/grafana/grafana/issues/5740), thx [@lpic10](https://github.com/lpic10)
+* **CLI**: Make it possible to reset the admin password using the grafana-cli. [#5479](https://github.com/grafana/grafana/issues/5479)
+* **Influxdb**: Support multiple tags in InfluxDB annotations. [#4550](https://github.com/grafana/grafana/pull/4550), thx [@adrianlzt](https://github.com/adrianlzt)
+* **LDAP**:  Basic Auth now supports LDAP username and password, [#6940](https://github.com/grafana/grafana/pull/6940), thx [@utkarshcmu](https://github.com/utkarshcmu)
+* **LDAP**: Now works with Auth Proxy, role and organisation mapping & sync will regularly be performed. [#6895](https://github.com/grafana/grafana/pull/6895), thx [@Seuf](https://github.com/seuf)
+* **Alerting**: Adds OK as no data option. [#6866](https://github.com/grafana/grafana/issues/6866)
+* **Alert list**: Order alerts based on state. [#6676](https://github.com/grafana/grafana/issues/6676)
+* **Alerting**: Add api endpoint for pausing all alerts. [#6589](https://github.com/grafana/grafana/issues/6589)
+* **Panel**: Added help text for panels. [#4079](https://github.com/grafana/grafana/issues/4079), thx [@utkarshcmu](https://github.com/utkarshcmu)
+
+### Bugfixes
+* **API**: HTTP API for deleting org returning incorrect message for a non-existing org [#6679](https://github.com/grafana/grafana/issues/6679)
+* **Dashboard**: Posting empty dashboard result in corrupted dashboard [#5443](https://github.com/grafana/grafana/issues/5443)
+* **Logging**: Fixed logging level confing issue [#6978](https://github.com/grafana/grafana/issues/6978)
+* **Notifications**: Remove html escaping the email subject. [#6905](https://github.com/grafana/grafana/issues/6905)
+* **Influxdb**: Fixes broken field dropdown when using template vars as measurement. [#6473](https://github.com/grafana/grafana/issues/6473)
+
+# 4.0.2 (2016-12-08)
+
+### Enhancements
+* **Playlist**: Add support for kiosk mode [#6727](https://github.com/grafana/grafana/issues/6727)
+
+### Bugfixes
+* **Alerting**: Add alert message to webhook notifications [#6807](https://github.com/grafana/grafana/issues/6807)
+* **Alerting**: Fixes a bug where avg() reducer treated null as zero. [#6879](https://github.com/grafana/grafana/issues/6879)
+* **PNG Rendering**: Fix for server side rendering when using non default http addr bind and domain setting [#6813](https://github.com/grafana/grafana/issues/6813)
+* **PNG Rendering**: Fix for server side rendering when setting enforce_domain to true [#6769](https://github.com/grafana/grafana/issues/6769)
+* **Webhooks**: Add content type json to outgoing webhooks [#6822](https://github.com/grafana/grafana/issues/6822)
+* **Keyboard shortcut**: Fixed zoom out shortcut [#6837](https://github.com/grafana/grafana/issues/6837)
+* **Webdav**: Adds basic auth headers to webdav uploader [#6779](https://github.com/grafana/grafana/issues/6779)
+
+# 4.0.1 (2016-12-02)
+
+> **Notice**
+4.0.0 had serious connection pooling issue when using a data source in proxy access. This bug caused lots of resource issues
+due to too many connections/file handles on the data source backend. This problem is fixed in this release.
+
+### Bugfixes
+* **Metrics**: Fixes nil pointer dereference on my arm build [#6749](https://github.com/grafana/grafana/issues/6749)
+* **Data proxy**: Fixes a tcp pooling issue in the datasource reverse proxy [#6759](https://github.com/grafana/grafana/issues/6759)
+
+# 4.0-stable (2016-11-29)
+
+### Bugfixes
+* **Server-side rendering**: Fixed address used when rendering panel via phantomjs and using non default http_addr config [#6660](https://github.com/grafana/grafana/issues/6660)
+* **Graph panel**: Fixed graph panel tooltip sort order issue [#6648](https://github.com/grafana/grafana/issues/6648)
+* **Unsaved changes**: You now navigate to the intended page after saving in the unsaved changes dialog [#6675](https://github.com/grafana/grafana/issues/6675)
+* **TLS Client Auth**: Support for TLS client authentication for datasource proxies [#2316](https://github.com/grafana/grafana/issues/2316)
+* **Alerts out of sync**: Saving dashboards with broken alerts causes sync problem[#6576](https://github.com/grafana/grafana/issues/6576)
+* **Alerting**: Saving an alert with condition "HAS NO DATA" throws an error[#6701](https://github.com/grafana/grafana/issues/6701)
+* **Config**: Improve error message when parsing broken config file [#6731](https://github.com/grafana/grafana/issues/6731)
+* **Table**: Render empty dates as - instead of current date [#6728](https://github.com/grafana/grafana/issues/6728)
+
+# 4.0-beta2 (2016-11-21)
+
+### Bugfixes
+* **Graph Panel**: Log base scale on right Y-axis had no effect, max value calc was not applied, [#6534](https://github.com/grafana/grafana/issues/6534)
+* **Graph Panel**: Bar width if bars was only used in series override, [#6528](https://github.com/grafana/grafana/issues/6528)
+* **UI/Browser**: Fixed issue with page/view header gradient border not showing in Safari, [#6530](https://github.com/grafana/grafana/issues/6530)
+* **Cloudwatch**: Fixed cloudwatch datasource requesting to many datapoints, [#6544](https://github.com/grafana/grafana/issues/6544)
+* **UX**: Panel Drop zone visible after duplicating panel, and when entering fullscreen/edit view, [#6598](https://github.com/grafana/grafana/issues/6598)
+* **Templating**: Newly added variable was not visible directly only after dashboard reload, [#6622](https://github.com/grafana/grafana/issues/6622)
+
+### Enhancements
+* **Singlestat**: Support repeated template variables in prefix/postfix [#6595](https://github.com/grafana/grafana/issues/6595)
+* **Templating**: Don't persist variable options with refresh option [#6586](https://github.com/grafana/grafana/issues/6586)
+* **Alerting**: Add ability to have OR conditions (and mixing AND & OR) [#6579](https://github.com/grafana/grafana/issues/6579)
+* **InfluxDB**: Fix for Ad-Hoc Filters variable & changing dashboards [#6821](https://github.com/grafana/grafana/issues/6821)
+
+# 4.0-beta1 (2016-11-09)
 
 ### Enhancements
 * **Login**: Adds option to disable username/password logins, closes [#4674](https://github.com/grafana/grafana/issues/4674)
@@ -11,17 +502,20 @@
 * **Database**: Allow database config using one propertie, closes [#5456](https://github.com/grafana/grafana/pull/5456)
 * **Graphite**: Add support for groupByNodes, closes [#5613](https://github.com/grafana/grafana/pull/5613)
 * **Influxdb**: Add support for elapsed(), closes [#5827](https://github.com/grafana/grafana/pull/5827)
+* **OpenTSDB**: Add support for explicitTags for OpenTSDB>=2.3, closes [#6360](https://github.com/grafana/grafana/pull/6361)
 * **OAuth**: Add support for generic oauth, closes [#4718](https://github.com/grafana/grafana/pull/4718)
 * **Cloudwatch**: Add support to expand multi select template variable, closes [#5003](https://github.com/grafana/grafana/pull/5003)
-* **Graph Panel**: Now supports flexible lower/upper bounds on Y-Max and Y-Min, PR [#5720](https://github.com/grafana/grafana/pull/5720)
 * **Background Tasks**: Now support automatic purging of old snapshots, closes [#4087](https://github.com/grafana/grafana/issues/4087)
 * **Background Tasks**: Now support automatic purging of old rendered images, closes [#2172](https://github.com/grafana/grafana/issues/2172)
+* **Dashboard**: After inactivity hide nav/row actions, fade to nice clean view, can be toggled with `d v`, also added kiosk mode, toggled via `d k` [#6476](https://github.com/grafana/grafana/issues/6476)
+* **Dashboard**: Improved dashboard row menu & add panel UX [#6442](https://github.com/grafana/grafana/issues/6442)
+* **Graph Panel**: Support for stacking null values [#2912](https://github.com/grafana/grafana/issues/2912), [#6287](https://github.com/grafana/grafana/issues/6287), thanks @benrubson!
 
 ### Breaking changes
 * **SystemD**: Change systemd description, closes [#5971](https://github.com/grafana/grafana/pull/5971)
 * **lodash upgrade**: Upgraded lodash from 2.4.2 to 4.15.0, this contains a number of breaking changes that could effect plugins. closes [#6021](https://github.com/grafana/grafana/pull/6021)
 
-### Bugfixes
+### Bug fixes
 * **Table Panel**: Fixed problem when switching to Mixed datasource in metrics tab, fixes [#5999](https://github.com/grafana/grafana/pull/5999)
 * **Playlist**: Fixed problem with play order not matching order defined in playlist, fixes [#5467](https://github.com/grafana/grafana/pull/5467)
 * **Graph panel**: Fixed problem with auto decimals on y axis when datamin=datamax, fixes [#6070](https://github.com/grafana/grafana/pull/6070)
@@ -29,6 +523,8 @@
 * **Elasticsearch**: Fix for query template variable when looking up terms without query, no longer relies on elasticsearch default field, fixes [#3887](https://github.com/grafana/grafana/pull/3887)
 * **Elasticsearch**: Fix for displaying IP address used in terms aggregations, fixes [#4393](https://github.com/grafana/grafana/pull/4393)
 * **PNG Rendering**: Fix for server side rendering when using auth proxy, fixes [#5906](https://github.com/grafana/grafana/pull/5906)
+* **OpenTSDB**: Fixed multi-value nested templating for opentsdb, fixes [#6455](https://github.com/grafana/grafana/pull/6455)
+* **Playlist**: Remove playlist items when dashboard is removed, fixes [#6292](https://github.com/grafana/grafana/issues/6292)
 
 # 3.1.2 (unreleased)
 * **Templating**: Fixed issue when combining row & panel repeats, fixes [#5790](https://github.com/grafana/grafana/issues/5790)
@@ -596,7 +1092,7 @@ Grafana 2.x is fundamentally different from 1.x; it now ships with an integrated
 
 # 1.8.0 (2014-09-22)
 
-Read this [blog post](http://grafana.org/blog/2014/09/11/grafana-1-8-0-rc1-released.html) for an overview of all improvements.
+Read this [blog post](https://grafana.com/blog/2014/09/11/grafana-1.8.0-rc1-released) for an overview of all improvements.
 
 **Fixes**
 - [Issue #802](https://github.com/grafana/grafana/issues/802). Annotations: Fix when using InfluxDB datasource

+ 46 - 0
CODE_OF_CONDUCT.md

@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@grafana.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/

+ 4 - 3
Gruntfile.js

@@ -22,16 +22,17 @@ module.exports = function (grunt) {
     }
   }
 
+  config.coverage = grunt.option('coverage');
   config.phjs = grunt.option('phjsToRelease');
-
   config.pkg.version = grunt.option('pkgVer') || config.pkg.version;
+
   console.log('Version', config.pkg.version);
 
   // load plugins
   require('load-grunt-tasks')(grunt);
 
   // load task definitions
-  grunt.loadTasks('tasks');
+  grunt.loadTasks('./scripts/grunt');
 
   // Utility function to load plugin settings into config
   function loadConfig(config,path) {
@@ -46,7 +47,7 @@ module.exports = function (grunt) {
   }
 
   // Merge that object with what with whatever we have here
-  loadConfig(config,'./tasks/options/');
+  loadConfig(config,'./scripts/grunt/options/');
   // pass the config to grunt
   grunt.initConfig(config);
 };

+ 1 - 1
LICENSE.md

@@ -1,4 +1,4 @@
-Copyright 2014-2016 Torkel Ödegaard, Raintank Inc.
+Copyright 2014-2017 Torkel Ödegaard, Raintank Inc.
 
 Licensed under the Apache License, Version 2.0 (the "License"); you
 may not use this file except in compliance with the License. You may

+ 2 - 2
Makefile

@@ -4,9 +4,9 @@ deps-go:
 	go run build.go setup
 
 deps-js:
-	npm install
+	yarn install --pure-lockfile --no-progress
 
-deps: deps-go deps-js
+deps: deps-js
 
 build-go:
 	go run build.go build

+ 28 - 0
PLUGIN_DEV.md

@@ -0,0 +1,28 @@
+# Plugin Development 
+
+This document is not meant as complete guide for developing plugins but more as a changelog for changes in
+Grafana that can impact plugin development. When ever you as plugin author encounter an issue with your plugin after
+upgrading Grafana please check here before creating an issue. 
+
+## Links
+
+- [Datasource plugin written in typescript](https://github.com/grafana/typescript-template-datasource)
+- [Simple json dataource plugin](https://github.com/grafana/simple-json-datasource)
+- [Plugin development guide](http://docs.grafana.org/plugins/developing/development/)
+
+## Changes in v4.6
+
+This version of Grafana has big changes that will impact a limited set of plugins. We moved from systemjs to webpack
+for built-in plugins & everything internal. External plugins still use systemjs but now with a limited 
+set of Grafana components they can import. Plugins can depend on libs like lodash & moment and internal components 
+like before using the same import paths. However since everything in Grafana is no longer accessible, a few plugins could encounter issues when importing a Grafana dependency. 
+
+[List of exposed components plugins can import/require](https://github.com/grafana/grafana/blob/master/public/app/features/plugins/plugin_loader.ts#L48)
+
+If you think we missed exposing a crucial lib or Grafana component let us know by opening an issue.  
+
+### Deprecated components 
+
+The angular directive `<spectrum-picker>` is now deprecated (will still work for a version more) but we recommend plugin authors
+to upgrade to new `<color-picker color="ctrl.color" onChange="ctrl.onSparklineColorChange"></color-picker>`
+

+ 48 - 99
README.md

@@ -1,70 +1,16 @@
-[Grafana](http://grafana.org) [![Circle CI](https://circleci.com/gh/grafana/grafana.svg?style=svg)](https://circleci.com/gh/grafana/grafana) [![Coverage Status](https://coveralls.io/repos/grafana/grafana/badge.png)](https://coveralls.io/r/grafana/grafana)
+[Grafana](https://grafana.com) [![Circle CI](https://circleci.com/gh/grafana/grafana.svg?style=svg)](https://circleci.com/gh/grafana/grafana) [![Go Report Card](https://goreportcard.com/badge/github.com/grafana/grafana)](https://goreportcard.com/report/github.com/grafana/grafana) [![codecov](https://codecov.io/gh/grafana/grafana/branch/master/graph/badge.svg)](https://codecov.io/gh/grafana/grafana)
 ================
-[Website](http://grafana.org) |
+[Website](https://grafana.com) |
 [Twitter](https://twitter.com/grafana) |
-[IRC](https://webchat.freenode.net/?channels=grafana) |
-[![Slack](https://brandfolder.com/api/favicon/icon?size=16&domain=www.slack.com)](http://slack.raintank.io)
-[Slack](http://slack.raintank.io) |
-[Email](mailto:contact@grafana.org)
+[Community & Forum](https://community.grafana.com)
 
 Grafana is an open source, feature rich metrics dashboard and graph editor for
 Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB.
 
-![](http://grafana.org/assets/img/start_page_bg.png)
-
-- [Install instructions](http://docs.grafana.org/installation/)
-- [What's New in Grafana 2.0](http://docs.grafana.org/guides/whats-new-in-v2/)
-- [What's New in Grafana 2.1](http://docs.grafana.org/guides/whats-new-in-v2-1/)
-- [What's New in Grafana 2.5](http://docs.grafana.org/guides/whats-new-in-v2-5/)
-- [What's New in Grafana 3.0](http://docs.grafana.org/guides/whats-new-in-v3/)
-
-## Features
-### Graphite Target Editor
-- Graphite target expression parser
-- Feature rich query composer
-- Quickly add and edit functions & parameters
-- Templated queries
-- [See it in action](http://docs.grafana.org/datasources/graphite/)
-
-### Graphing
-- Fast rendering, even over large timespans
-- Click and drag to zoom
-- Multiple Y-axis, logarithmic scales
-- Bars, Lines, Points
-- Smart Y-axis formatting
-- Series toggles & color selector
-- Legend values, and formatting options
-- Grid thresholds, axis labels
-- [Annotations](http://docs.grafana.org/reference/annotations/)
-- Any panel can be rendered to PNG (server side using phantomjs)
-
-### Dashboards
-- Create, edit, save & search dashboards
-- Change column spans and row heights
-- Drag and drop panels to rearrange
-- [Templating](http://docs.grafana.org/reference/templating/)
-- [Scripted dashboards](http://docs.grafana.org/reference/scripting/)
-- [Dashboard playlists](http://docs.grafana.org/reference/playlist/)
-- [Time range controls](http://docs.grafana.org/reference/timerange/)
-- [Share snapshots publicly](http://docs.grafana.org/v2.0/reference/sharing/)
-
-### Elasticsearch
-- Feature rich query editor UI
-
-### InfluxDB
-- Use InfluxDB as a metric data source, annotation source
-- Query editor with series and column typeahead, easy group by and function selection
-
-### OpenTSDB
-- Use as metric data source
-- Query editor with metric name typeahead and tag filtering
-
-## Requirements
-There are no dependencies except an external time series data store. For dashboards and user accounts Grafana can use an embedded
-database (sqlite3) or you can use an external SQL data base like MySQL or Postgres.
+![](http://docs.grafana.org/assets/img/features/dashboard_ex1.png)
 
 ## Installation
-Head to [grafana.org](http://docs.grafana.org/installation/) and [download](http://grafana.org/download/)
+Head to [docs.grafana.org](http://docs.grafana.org/installation/) and [download](https://grafana.com/get)
 the latest release.
 
 If you have any problems please read the [troubleshooting guide](http://docs.grafana.org/installation/troubleshooting/).
@@ -74,67 +20,55 @@ Be sure to read the [getting started guide](http://docs.grafana.org/guides/getti
 
 ## Run from master
 If you want to build a package yourself, or contribute. Here is a guide for how to do that. You can always find
-the latest master builds [here](http://grafana.org/builds)
+the latest master builds [here](https://grafana.com/grafana/download)
 
 ### Dependencies
 
-- Go 1.7
-- NodeJS v4+
-
-### Get Code
-
-```bash
-go get github.com/grafana/grafana
-```
-
-Since imports of dependencies use the absolute path `github.com/grafana/grafana` within the `$GOPATH`,
-you will need to put your version of the code in `$GOPATH/src/github.com/grafana/grafana` to be able
-to develop and build grafana on a cloned repository. To do so, you can clone your forked repository
-directly to `$GOPATH/src/github.com/grafana` or you can create a symbolic link from your version
-of the code to `$GOPATH/src/github.com/grafana/grafana`. The last options makes it possible to change
-easily the grafana repository you want to build.
-```bash
-go get github.com/*your_account*/grafana
-mkdir $GOPATH/src/github.com/grafana
-ln -s  $GOPATH/src/github.com/*your_account*/grafana $GOPATH/src/github.com/grafana/grafana
-```
+- Go 1.9
+- NodeJS LTS
 
 ### Building the backend
 ```bash
-cd $GOPATH/src/github.com/grafana/grafana
+go get github.com/grafana/grafana
+cd ~/go/src/github.com/grafana/grafana
 go run build.go setup
 go run build.go build
 ```
 
 ### Building frontend assets
 
-To build less to css for the frontend you will need a recent version of **node (v4+)**,
-npm (v2.5.0) and grunt (v0.4.5). Run the following:
+For this you need nodejs (v.6+).
 
 ```bash
-npm install
+npm install -g yarn
+yarn install --pure-lockfile
 npm run build
 ```
 
-To build the frontend assets only on changes:
+To rebuild frontend assets (typescript, sass etc) as you change them start the watcher via.
+
+```bash
+npm run watch
+```
+
+Run tests
+```bash
+npm run test
+```
 
+Run tests in watch mode
 ```bash
-sudo npm install -g grunt-cli # to do only once to install grunt command line interface
-grunt watch
+npm run watch-test
 ```
 
 ### Recompile backend on source change
+
 To rebuild on source change.
 ```bash
 go get github.com/Unknwon/bra
 bra run
 ```
 
-### Running
-```bash
-./bin/grafana-server
-```
-
 Open grafana in your browser (default: `http://localhost:3000`) and login with admin user (default: `user/pass = admin/admin`).
 
 ### Dev config
@@ -143,21 +77,36 @@ Create a custom.ini in the conf directory to override default configuration opti
 You only need to add the options you want to override. Config files are applied in the order of:
 
 1. grafana.ini
-2. dev.ini (if found)
-3. custom.ini
+1. custom.ini
+
+In your custom.ini uncomment (remove the leading `;`) sign. And set `app_mode = development`.
 
-## Create a pull request
-Before or after you create a pull request, sign the [contributor license agreement](http://docs.grafana.org/project/cla/).
+### Running tests
+
+- You can run backend Golang tests using "go test ./pkg/...".
+- Execute all frontend tests with "npm run test"
+
+Writing & watching frontend tests (we have two test runners)
+
+- jest for all new tests that do not require browser context (React+more)
+   - Start watcher: `npm run jest`
+   - Jest will run all test files that end with the name ".jest.ts"
+- karma + mocha is used for testing angularjs components. We do want to migrate these test to jest over time (if possible).
+  - Start watcher: `npm run karma`
+  - Karma+Mocha runs all files that end with the name "_specs.ts".
 
 ## Contribute
+
 If you have any idea for an improvement or found a bug do not hesitate to open an issue.
 And if you have time clone this repo and submit a pull request and help me make Grafana
 the kickass metrics & devops dashboard we all dream about!
 
-Before creating a pull request be sure that "grunt test" runs without any style or unit test errors, also
-please [sign the CLA](http://docs.grafana.org/project/cla/)
+## Plugin development
+
+Checkout the [Plugin Development Guide](http://docs.grafana.org/plugins/developing/development/) and checkout the [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) file for changes in Grafana that relate to
+plugin development.
 
 ## License
 
 Grafana is distributed under Apache 2.0 License.
-Work in progress Grafana 2.0 (with included Grafana backend)
+

+ 36 - 0
ROADMAP.md

@@ -0,0 +1,36 @@
+# Roadmap (2017-10-31)
+
+This roadmap is a tentative plan for the core development team. Things change constantly as PRs come in and priorities change. 
+But it will give you an idea of our current vision and plan. 
+
+### Short term (1-4 months)
+
+ - Release Grafana v5
+  - User groups
+  - Dashboard folders
+  - Dashboard & folder permissions (assigned to users or groups)
+  - New Dashboard layout engine
+  - New sidemenu & nav UX
+  - Elasticsearch alerting
+  - React migration foundation (core components) 
+  - Graphite 1.1 Tags Support
+  
+### Long term (4 - 8 months)
+
+- Backend plugins to support more Auth options, Alerting data sources & notifications
+- Alerting improvements (silence, per series tracking, etc)
+- Dashboard as configuration and other automation / provisioning improvements
+- Progress on React migration
+- Change visualization (panel type) on the fly. 
+- Multi stat panel (vertical version of singlestat with bars/graph mode with big number etc) 
+- Repeat panel by query results 
+
+### In a distant future far far away
+
+- Meta queries 
+- Integrated light weight TSDB
+- Web socket & live data sources
+
+### Outside contributions
+We know this is being worked on right now by contributors (and we hope to merge it when it's ready). 
+

+ 21 - 5
appveyor.yml

@@ -5,14 +5,19 @@ os: Windows Server 2012 R2
 clone_folder: c:\gopath\src\github.com\grafana\grafana
 
 environment:
-  nodejs_version: "5"
+  nodejs_version: "6"
   GOPATH: c:\gopath
+  GOVERSION: 1.9.2
 
 install:
+  - rmdir c:\go /s /q
   # install nodejs and npm
   - ps: Install-Product node $env:nodejs_version
-  - npm install
+  - npm install -g yarn --silent
+  - yarn install --pure-lockfile --no-progress
   - npm install -g grunt-cli
+  - appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.zip
+  - 7z x go%GOVERSION%.windows-amd64.zip -y -oC:\ > NUL
   # install gcc (needed for sqlite3)
   - choco install -y --limit-output mingw
   - set PATH=C:\tools\mingw64\bin;%PATH%
@@ -20,18 +25,29 @@ install:
   - echo %GOPATH%
   - go version
   - go env
-  - go run build.go setup
+  # - go run build.go setup
 
 build_script:
   - go run build.go build
   - grunt release
-  - go run build.go sha1-dist
+  - go run build.go sha-dist
   - cp dist/* .
+  - go test -v ./pkg/...
 
 artifacts:
   - path: grafana-*windows-*.*
     name: binzip
+    type: zip
 
 deploy:
   - provider: Environment
-    name: GrafanaBuildsS3
+    name: GrafanaReleaseMaster
+    on:
+      buildType: master
+
+  - provider: Environment
+    name: GrafanaReleaseRelease
+    on:
+      buildType: release
+
+

+ 0 - 25
bower.json

@@ -1,25 +0,0 @@
-{
-  "name": "grafana",
-  "version": "2.0.2",
-  "homepage": "https://github.com/grafana/grafana",
-  "authors": [],
-  "license": "Apache 2.0",
-  "ignore": [
-    "**/.*",
-    "node_modules",
-    "bower_components",
-    "public/vendor/",
-    "test",
-    "tests"
-  ],
-  "dependencies": {
-    "jquery": "3.1.0",
-    "lodash": "4.15.0",
-    "angular": "1.5.8",
-    "angular-route": "1.5.8",
-    "angular-mocks": "1.5.8",
-    "angular-sanitize": "1.5.8",
-    "angular-native-dragdrop": "1.2.2",
-    "angular-bindonce": "0.3.3"
-  }
-}

+ 79 - 46
build.go

@@ -5,7 +5,7 @@ package main
 import (
 	"bytes"
 	"crypto/md5"
-	"crypto/sha1"
+	"crypto/sha256"
 	"encoding/json"
 	"flag"
 	"fmt"
@@ -14,6 +14,7 @@ import (
 	"log"
 	"os"
 	"os/exec"
+	"path"
 	"path/filepath"
 	"regexp"
 	"runtime"
@@ -37,19 +38,18 @@ var (
 	race                  bool
 	phjsToRelease         string
 	workingDir            string
+	includeBuildNumber    bool     = true
+	buildNumber           int      = 0
 	binaries              []string = []string{"grafana-server", "grafana-cli"}
 )
 
-const minGoVersion = 1.7
+const minGoVersion = 1.8
 
 func main() {
 	log.SetOutput(os.Stdout)
 	log.SetFlags(0)
 
 	ensureGoPath()
-	readVersionFromPackageJson()
-
-	log.Printf("Version: %s, Linux Version: %s, Package Iteration: %s\n", version, linuxPackageVersion, linuxPackageIteration)
 
 	flag.StringVar(&goarch, "goarch", runtime.GOARCH, "GOARCH")
 	flag.StringVar(&goos, "goos", runtime.GOOS, "GOOS")
@@ -59,8 +59,14 @@ func main() {
 	flag.StringVar(&pkgArch, "pkg-arch", "", "PKG ARCH")
 	flag.StringVar(&phjsToRelease, "phjs", "", "PhantomJS binary")
 	flag.BoolVar(&race, "race", race, "Use race detector")
+	flag.BoolVar(&includeBuildNumber, "includeBuildNumber", includeBuildNumber, "IncludeBuildNumber in package name")
+	flag.IntVar(&buildNumber, "buildNumber", 0, "Build number from CI system")
 	flag.Parse()
 
+	readVersionFromPackageJson()
+
+	log.Printf("Version: %s, Linux Version: %s, Package Iteration: %s\n", version, linuxPackageVersion, linuxPackageIteration)
+
 	if flag.NArg() == 0 {
 		log.Println("Usage: go run build.go build")
 		return
@@ -73,6 +79,10 @@ func main() {
 		case "setup":
 			setup()
 
+		case "build-cli":
+			clean()
+			build("grafana-cli", "./pkg/cmd/grafana-cli", []string{})
+
 		case "build":
 			clean()
 			for _, binary := range binaries {
@@ -85,25 +95,23 @@ func main() {
 
 		case "package":
 			grunt(gruntBuildArg("release")...)
-			createLinuxPackages()
-			sha1FilesInDist()
+      if runtime.GOOS != "windows" {
+			  createLinuxPackages()
+      }
 
 		case "pkg-rpm":
 			grunt(gruntBuildArg("release")...)
 			createRpmPackages()
-			sha1FilesInDist()
 
 		case "pkg-deb":
 			grunt(gruntBuildArg("release")...)
 			createDebPackages()
-			sha1FilesInDist()
 
-    case "sha1-dist":
-      sha1FilesInDist()
+		case "sha-dist":
+			shaFilesInDist()
 
 		case "latest":
 			makeLatestDistCopies()
-			sha1FilesInDist()
 
 		case "clean":
 			clean()
@@ -115,14 +123,24 @@ func main() {
 }
 
 func makeLatestDistCopies() {
-	rpmIteration := "-1"
-	if linuxPackageIteration != "" {
-		rpmIteration = linuxPackageIteration
+	files, err := ioutil.ReadDir("dist")
+	if err != nil {
+		log.Fatalf("failed to create latest copies. Cannot read from /dist")
 	}
 
-	runError("cp", fmt.Sprintf("dist/grafana_%v-%v_amd64.deb", linuxPackageVersion, linuxPackageIteration), "dist/grafana_latest_amd64.deb")
-	runError("cp", fmt.Sprintf("dist/grafana-%v-%v.x86_64.rpm", linuxPackageVersion, rpmIteration), "dist/grafana-latest-1.x86_64.rpm")
-	runError("cp", fmt.Sprintf("dist/grafana-%v-%v.linux-x64.tar.gz", linuxPackageVersion, linuxPackageIteration), "dist/grafana-latest.linux-x64.tar.gz")
+	latestMapping := map[string]string{
+		".deb":    "dist/grafana_latest_amd64.deb",
+		".rpm":    "dist/grafana-latest-1.x86_64.rpm",
+		".tar.gz": "dist/grafana-latest.linux-x64.tar.gz",
+	}
+
+	for _, file := range files {
+		for extension, fullName := range latestMapping {
+			if strings.HasSuffix(file.Name(), extension) {
+				runError("cp", path.Join("dist", file.Name()), fullName)
+			}
+		}
+	}
 }
 
 func readVersionFromPackageJson() {
@@ -153,7 +171,13 @@ func readVersionFromPackageJson() {
 	}
 
 	// add timestamp to iteration
-	linuxPackageIteration = fmt.Sprintf("%d%s", time.Now().Unix(), linuxPackageIteration)
+	if includeBuildNumber {
+		if buildNumber != 0 {
+			linuxPackageIteration = fmt.Sprintf("%d%s", buildNumber, linuxPackageIteration)
+		} else {
+			linuxPackageIteration = fmt.Sprintf("%d%s", time.Now().Unix(), linuxPackageIteration)
+		}
+	}
 }
 
 type linuxPackageOptions struct {
@@ -163,7 +187,6 @@ type linuxPackageOptions struct {
 	serverBinPath          string
 	cliBinPath             string
 	configDir              string
-	configFilePath         string
 	ldapFilePath           string
 	etcDefaultPath         string
 	etcDefaultFilePath     string
@@ -184,8 +207,6 @@ func createDebPackages() {
 		homeDir:                "/usr/share/grafana",
 		binPath:                "/usr/sbin",
 		configDir:              "/etc/grafana",
-		configFilePath:         "/etc/grafana/grafana.ini",
-		ldapFilePath:           "/etc/grafana/ldap.toml",
 		etcDefaultPath:         "/etc/default",
 		etcDefaultFilePath:     "/etc/default/grafana-server",
 		initdScriptFilePath:    "/etc/init.d/grafana-server",
@@ -206,8 +227,6 @@ func createRpmPackages() {
 		homeDir:                "/usr/share/grafana",
 		binPath:                "/usr/sbin",
 		configDir:              "/etc/grafana",
-		configFilePath:         "/etc/grafana/grafana.ini",
-		ldapFilePath:           "/etc/grafana/ldap.toml",
 		etcDefaultPath:         "/etc/sysconfig",
 		etcDefaultFilePath:     "/etc/sysconfig/grafana-server",
 		initdScriptFilePath:    "/etc/init.d/grafana-server",
@@ -218,7 +237,7 @@ func createRpmPackages() {
 		defaultFileSrc: "packaging/rpm/sysconfig/grafana-server",
 		systemdFileSrc: "packaging/rpm/systemd/grafana-server.service",
 
-		depends: []string{"initscripts", "fontconfig"},
+		depends: []string{"/sbin/service", "fontconfig", "freetype", "urw-fonts"},
 	})
 }
 
@@ -252,21 +271,15 @@ func createPackage(options linuxPackageOptions) {
 	runPrint("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", filepath.Join(packageRoot, options.homeDir))
 	// remove bin path
 	runPrint("rm", "-rf", filepath.Join(packageRoot, options.homeDir, "bin"))
-	// copy sample ini file to /etc/grafana
-	runPrint("cp", "conf/sample.ini", filepath.Join(packageRoot, options.configFilePath))
-	// copy sample ldap toml config file to /etc/grafana/ldap.toml
-	runPrint("cp", "conf/ldap.toml", filepath.Join(packageRoot, options.ldapFilePath))
 
 	args := []string{
 		"-s", "dir",
 		"--description", "Grafana",
 		"-C", packageRoot,
 		"--vendor", "Grafana",
-		"--url", "http://grafana.org",
+		"--url", "https://grafana.com",
 		"--license", "\"Apache 2.0\"",
-		"--maintainer", "contact@grafana.org",
-		"--config-files", options.configFilePath,
-		"--config-files", options.ldapFilePath,
+		"--maintainer", "contact@grafana.com",
 		"--config-files", options.initdScriptFilePath,
 		"--config-files", options.etcDefaultFilePath,
 		"--config-files", options.systemdServiceFilePath,
@@ -276,6 +289,14 @@ func createPackage(options linuxPackageOptions) {
 		"-p", "./dist",
 	}
 
+	if options.packageType == "rpm" {
+		args = append(args, "--rpm-posttrans", "packaging/rpm/control/posttrans")
+	}
+
+	if options.packageType == "deb" {
+		args = append(args, "--deb-no-default-config-files")
+	}
+
 	if pkgArch != "" {
 		args = append(args, "-a", pkgArch)
 	}
@@ -326,11 +347,20 @@ func ChangeWorkingDir(dir string) {
 }
 
 func grunt(params ...string) {
-	runPrint("./node_modules/.bin/grunt", params...)
+  if runtime.GOOS == "windows" {
+    runPrint(`.\node_modules\.bin\grunt`, params...)
+  } else {
+    runPrint("./node_modules/.bin/grunt", params...)
+  }
 }
 
 func gruntBuildArg(task string) []string {
-	args := []string{task, fmt.Sprintf("--pkgVer=%v-%v", linuxPackageVersion, linuxPackageIteration)}
+	args := []string{task}
+	if includeBuildNumber {
+		args = append(args, fmt.Sprintf("--pkgVer=%v-%v", linuxPackageVersion, linuxPackageIteration))
+	} else {
+		args = append(args, fmt.Sprintf("--pkgVer=%v", version))
+	}
 	if pkgArch != "" {
 		args = append(args, fmt.Sprintf("--arch=%v", pkgArch))
 	}
@@ -425,14 +455,10 @@ func setBuildEnv() {
 }
 
 func getGitSha() string {
-	v, err := runError("git", "describe", "--always", "--dirty")
+	v, err := runError("git", "rev-parse", "--short", "HEAD")
 	if err != nil {
 		return "unknown-dev"
 	}
-	v = versionRe.ReplaceAllFunc(v, func(s []byte) []byte {
-		s[0] = '+'
-		return s
-	})
 	return string(v)
 }
 
@@ -510,29 +536,36 @@ func md5File(file string) error {
 	return out.Close()
 }
 
-func sha1FilesInDist() {
+func shaFilesInDist() {
 	filepath.Walk("./dist", func(path string, f os.FileInfo, err error) error {
-		if strings.Contains(path, ".sha1") == false {
-			sha1File(path)
+		if path == "./dist" {
+			return nil
+		}
+
+		if strings.Contains(path, ".sha256") == false {
+			err := shaFile(path)
+			if err != nil {
+				log.Printf("Failed to create sha file. error: %v\n", err)
+			}
 		}
 		return nil
 	})
 }
 
-func sha1File(file string) error {
+func shaFile(file string) error {
 	fd, err := os.Open(file)
 	if err != nil {
 		return err
 	}
 	defer fd.Close()
 
-	h := sha1.New()
+	h := sha256.New()
 	_, err = io.Copy(h, fd)
 	if err != nil {
 		return err
 	}
 
-	out, err := os.Create(file + ".sha1")
+	out, err := os.Create(file + ".sha256")
 	if err != nil {
 		return err
 	}

+ 34 - 8
circle.yml

@@ -1,31 +1,57 @@
 machine:
   node:
-    version: 5.11.1
+    version: 6.11.4
+  python:
+    version: 2.7.3
+  services:
+    - docker
   environment:
     GOPATH: "/home/ubuntu/.go_workspace"
     ORG_PATH: "github.com/grafana"
     REPO_PATH: "${ORG_PATH}/grafana"
-    GODIST: "go1.7.1.linux-amd64.tar.gz"
+    GODIST: "go1.9.2.linux-amd64.tar.gz"
   post:
-    - mkdir -p download
+    - mkdir -p ~/download
+    - mkdir -p ~/docker
     - test -e download/$GODIST || curl -o download/$GODIST https://storage.googleapis.com/golang/$GODIST
     - sudo rm -rf /usr/local/go
     - sudo tar -C /usr/local -xzf download/$GODIST
 
 dependencies:
+  cache_directories:
+    - "~/docker"
+    - "~/download"
   override:
     - rm -rf ${GOPATH}/src/${REPO_PATH}
     - mkdir -p ${GOPATH}/src/${ORG_PATH}
     - cp -r ~/grafana ${GOPATH}/src/${ORG_PATH}
+  pre:
+    - pip install awscli
+    - sudo apt-get update; sudo apt-get install rpm; sudo apt-get install expect
+    - ./scripts/build/build_container.sh
 
 test:
   override:
-     - bash scripts/circle-test.sh
+    - bash scripts/circle-test-frontend.sh
+    - bash scripts/circle-test-backend.sh
 
 deployment:
-  master:
+  gh_branch:
     branch: master
-    owner: grafana
     commands:
-      - ./scripts/trigger_grafana_packer.sh ${TRIGGER_GRAFANA_PACKER_CIRCLECI_TOKEN}
-      - ./scripts/trigger_windows_build.sh ${APPVEYOR_TOKEN}
+      - ./scripts/build/deploy.sh
+      - ./scripts/build/sign_packages.sh
+      - go run build.go sha-dist
+      - aws s3 sync ./dist s3://$BUCKET_NAME/master
+      - ./scripts/trigger_windows_build.sh ${APPVEYOR_TOKEN} ${CIRCLE_SHA1} master
+      - ./scripts/trigger_docker_build.sh ${TRIGGER_GRAFANA_PACKER_CIRCLECI_TOKEN}
+      - go run ./scripts/build/publish.go -apiKey ${GRAFANA_COM_API_KEY}
+  gh_tag:
+    tag: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
+    commands:
+      - ./scripts/build/deploy.sh
+      - ./scripts/build/sign_packages.sh
+      - go run build.go sha-dist
+      - aws s3 sync ./dist s3://$BUCKET_NAME/release
+      - ./scripts/trigger_windows_build.sh ${APPVEYOR_TOKEN} ${CIRCLE_SHA1} release
+      - ./scripts/trigger_docker_build.sh ${TRIGGER_GRAFANA_PACKER_CIRCLECI_TOKEN} ${CIRCLE_TAG}

+ 13 - 0
codecov.yml

@@ -0,0 +1,13 @@
+coverage:
+  precision: 2
+  round: down
+  range: "50...100"
+
+  status:
+    project: yes
+    patch: yes
+    changes: no
+
+comment:
+  layout: "diff"
+  behavior: "once"

+ 86 - 38
conf/defaults.ini

@@ -25,7 +25,7 @@ plugins = data/plugins
 
 #################################### Server ##############################
 [server]
-# Protocol (http or https)
+# Protocol (http, https, socket)
 protocol = http
 
 # The ip address to bind to, empty will bind to all interfaces
@@ -57,21 +57,31 @@ enable_gzip = false
 cert_file =
 cert_key =
 
+# Unix socket path
+socket = /tmp/grafana.sock
+
 #################################### Database ############################
 [database]
 # You can configure the database connection by specifying type, host, name, user and password
-# as seperate properties or as on string using the url propertie.
+# as separate properties or as on string using the url property.
 
 # Either "mysql", "postgres" or "sqlite3", it's your choice
 type = sqlite3
 host = 127.0.0.1:3306
 name = grafana
 user = root
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
 password =
 # Use either URL or the previous fields to configure the database
 # Example: mysql://user:secret@host:port/database
 url =
 
+# Max idle conn setting default is 2
+max_idle_conn = 2
+
+# Max conn setting default is 0 (mean not set)
+max_open_conn =
+
 # For "postgres", use either "disable", "require" or "verify-full"
 # For "mysql", use either "true", "false", or "skip-verify".
 ssl_mode = disable
@@ -112,6 +122,12 @@ cookie_secure = false
 session_life_time = 86400
 gc_interval_time = 86400
 
+#################################### Data proxy ###########################
+[dataproxy]
+
+# This enables data proxy logging, default is false
+logging = false
+
 #################################### Analytics ###########################
 [analytics]
 # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
@@ -120,11 +136,11 @@ gc_interval_time = 86400
 # Change this option to false to disable reporting.
 reporting_enabled = true
 
-# Set to false to disable all checks to https://grafana.net
-# for new vesions (grafana itself and plugins), check is used
+# Set to false to disable all checks to https://grafana.com
+# for new versions (grafana itself and plugins), check is used
 # in some UI views to notify that grafana or plugin update exists
 # This option does not cause any auto updates, nor send any information
-# only a GET request to http://grafana.net to get latest versions
+# only a GET request to https://grafana.com to get latest versions
 check_for_updates = true
 
 # Google Analytics universal tracking code, only enabled if you specify an id here
@@ -170,10 +186,10 @@ snapshot_TTL_days = 90
 #################################### Users ####################################
 [users]
 # disable user signup / registration
-allow_sign_up = true
+allow_sign_up = false
 
 # Allow non admin users to create organizations
-allow_org_create = true
+allow_org_create = false
 
 # Set to true to automatically assign new users to the default organization (id 1)
 auto_assign_org = true
@@ -190,10 +206,18 @@ login_hint = email or username
 # Default UI theme ("dark" or "light")
 default_theme = dark
 
+# External user management
+external_manage_link_url =
+external_manage_link_name =
+external_manage_info =
+
 [auth]
 # Set to true to disable (hide) the login form, useful if you use OAuth
 disable_login_form = false
 
+# Set to true to disable the signout link in the side menu. useful if you use auth.proxy
+disable_signout_menu = false
+
 #################################### Anonymous Auth ######################
 [auth.anonymous]
 # enable anonymous access
@@ -208,7 +232,7 @@ org_role = Viewer
 #################################### Github Auth #########################
 [auth.github]
 enabled = false
-allow_sign_up = false
+allow_sign_up = true
 client_id = some_id
 client_secret = some_secret
 scopes = user:email
@@ -221,7 +245,7 @@ allowed_organizations =
 #################################### Google Auth #########################
 [auth.google]
 enabled = false
-allow_sign_up = false
+allow_sign_up = true
 client_id = some_client_id
 client_secret = some_client_secret
 scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
@@ -229,11 +253,21 @@ auth_url = https://accounts.google.com/o/oauth2/auth
 token_url = https://accounts.google.com/o/oauth2/token
 api_url = https://www.googleapis.com/oauth2/v1/userinfo
 allowed_domains =
+hosted_domain =
 
-#################################### Grafana.net Auth ####################
+#################################### Grafana.com Auth ####################
+# legacy key names (so they work in env variables)
 [auth.grafananet]
 enabled = false
-allow_sign_up = false
+allow_sign_up = true
+client_id = some_id
+client_secret = some_secret
+scopes = user:email
+allowed_organizations =
+
+[auth.grafana_com]
+enabled = false
+allow_sign_up = true
 client_id = some_id
 client_secret = some_secret
 scopes = user:email
@@ -241,8 +275,9 @@ allowed_organizations =
 
 #################################### Generic OAuth #######################
 [auth.generic_oauth]
+name = OAuth
 enabled = false
-allow_sign_up = false
+allow_sign_up = true
 client_id = some_id
 client_secret = some_secret
 scopes = user:email
@@ -262,6 +297,8 @@ enabled = false
 header_name = X-WEBAUTH-USER
 header_property = username
 auto_sign_up = true
+ldap_sync_ttl = 60
+whitelist =
 
 #################################### Auth LDAP ###########################
 [auth.ldap]
@@ -274,11 +311,14 @@ allow_sign_up = true
 enabled = false
 host = localhost:25
 user =
+# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
 password =
 cert_file =
 key_file =
 skip_verify = false
 from_address = admin@grafana.localhost
+from_name = Grafana
+ehlo_identity =
 
 [emails]
 welcome_email_on_sign_up = false
@@ -288,7 +328,7 @@ templates_pattern = emails/*.html
 [log]
 # Either "console", "file", "syslog". Default is console and  file
 # Use space to separate multiple modes, e.g. "console file"
-mode = console, file
+mode = console file
 
 # Either "debug", "info", "warn", "error", "critical", default is "info"
 level = info
@@ -341,13 +381,6 @@ facility =
 # Syslog tag. By default, the process' argv[0] is used.
 tag =
 
-
-#################################### AMQP Event Publisher ################
-[event_publisher]
-enabled = false
-rabbitmq_url = amqp://localhost/
-exchange = grafana_events
-
 #################################### Dashboard JSON files ################
 [dashboards.json]
 enabled = false
@@ -389,23 +422,10 @@ global_api_key = -1
 global_session = -1
 
 #################################### Alerting ############################
-# docs about alerting can be found in /docs/sources/alerting/
-#              __.-/|
-#              \`o_O'
-#               =( )=  +----------------------------+
-#                 U|   | Alerting is still in alpha |
-#       /\  /\   / |   +----------------------------+
-#      ) /^\) ^\/ _)\     |
-#      )   /^\/   _) \    |
-#      )   _ /  / _)  \___|_
-#  /\  )/\/ ||  | )_)\___,|))
-# <  >      |(,,) )__)    |
-#  ||      /    \)___)\
-#  | \____(      )___) )____
-#   \______(_______;;;)__;;;)
-
 [alerting]
-# Makes it possible to turn off alert rule execution.
+# Disable alerting engine & UI features
+enabled = true
+# Makes it possible to turn off alert rule execution but alerting UI is visible
 execute_alerts = true
 
 #################################### Internal Grafana Metrics ############
@@ -421,15 +441,38 @@ address =
 prefix = prod.grafana.%(instance_name)s.
 
 [grafana_net]
-url = https://grafana.net
+url = https://grafana.com
+
+[grafana_com]
+url = https://grafana.com
+
+#################################### Distributed tracing ############
+[tracing.jaeger]
+# jaeger destination (ex localhost:6831)
+address =
+# tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
+always_included_tag =
+# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
+sampler_type = const
+# jaeger samplerconfig param
+# for "const" sampler, 0 or 1 for always false/true respectively
+# for "probabilistic" sampler, a probability between 0 and 1
+# for "rateLimiting" sampler, the number of spans per second
+# for "remote" sampler, param is the same as for "probabilistic"
+# and indicates the initial sampling rate before the actual one
+# is received from the mothership
+sampler_param = 1
 
 #################################### External Image Storage ##############
 [external_image_storage]
-# You can choose between (s3, webdav)
+# You can choose between (s3, webdav, gcs)
 provider =
 
 [external_image_storage.s3]
 bucket_url =
+bucket =
+region =
+path =
 access_key =
 secret_key =
 
@@ -437,3 +480,8 @@ secret_key =
 url =
 username =
 password =
+public_url =
+
+[external_image_storage.gcs]
+key_file =
+bucket =

+ 5 - 3
conf/ldap.toml

@@ -1,5 +1,6 @@
-# Set to true to log user information returned from LDAP
-verbose_logging = false
+# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
+# [log]
+# filters = ldap:debug
 
 [[servers]]
 # Ldap server host (specify multiple hosts space separated)
@@ -13,11 +14,12 @@ start_tls = false
 # set to true if you want to skip ssl cert validation
 ssl_skip_verify = false
 # set to the path to your root CA certificate or leave unset to use system defaults
-# root_ca_cert = /path/to/certificate.crt
+# root_ca_cert = "/path/to/certificate.crt"
 
 # Search user bind dn
 bind_dn = "cn=admin,dc=grafana,dc=org"
 # Search user bind password
+# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
 bind_password = 'grafana'
 
 # User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"

+ 77 - 39
conf/sample.ini

@@ -26,7 +26,7 @@
 #
 #################################### Server ####################################
 [server]
-# Protocol (http or https)
+# Protocol (http, https, socket)
 ;protocol = http
 
 # The ip address to bind to, empty will bind to all interfaces
@@ -59,6 +59,9 @@
 ;cert_file =
 ;cert_key =
 
+# Unix socket path
+;socket =
+
 #################################### Database ####################################
 [database]
 # You can configure the database connection by specifying type, host, name, user and password
@@ -69,6 +72,7 @@
 ;host = 127.0.0.1:3306
 ;name = grafana
 ;user = root
+# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
 ;password =
 
 # Use either URL or the previous fields to configure the database
@@ -81,6 +85,13 @@
 # For "sqlite3" only, path relative to data_path setting
 ;path = grafana.db
 
+# Max idle conn setting default is 2
+;max_idle_conn = 2
+
+# Max conn setting default is 0 (mean not set)
+;max_open_conn =
+
+
 #################################### Session ####################################
 [session]
 # Either "memory", "file", "redis", "mysql", "postgres", default is "file"
@@ -103,6 +114,13 @@
 # Session life time, default is 86400
 ;session_life_time = 86400
 
+#################################### Data proxy ###########################
+[dataproxy]
+
+# This enables data proxy logging, default is false
+;logging = false
+
+
 #################################### Analytics ####################################
 [analytics]
 # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
@@ -115,7 +133,7 @@
 # for new vesions (grafana itself and plugins), check is used
 # in some UI views to notify that grafana or plugin update exists
 # This option does not cause any auto updates, nor send any information
-# only a GET request to http://grafana.net to get latest versions
+# only a GET request to http://grafana.com to get latest versions
 ;check_for_updates = true
 
 # Google Analytics universal tracking code, only enabled if you specify an id here
@@ -175,10 +193,18 @@
 # Default UI theme ("dark" or "light")
 ;default_theme = dark
 
+# External user management, these options affect the organization users view
+;external_manage_link_url =
+;external_manage_link_name =
+;external_manage_info =
+
 [auth]
 # Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
 ;disable_login_form = false
 
+# Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false
+;disable_signout_menu = false
+
 #################################### Anonymous Auth ##########################
 [auth.anonymous]
 # enable anonymous access
@@ -193,7 +219,7 @@
 #################################### Github Auth ##########################
 [auth.github]
 ;enabled = false
-;allow_sign_up = false
+;allow_sign_up = true
 ;client_id = some_id
 ;client_secret = some_secret
 ;scopes = user:email,read:org
@@ -206,7 +232,7 @@
 #################################### Google Auth ##########################
 [auth.google]
 ;enabled = false
-;allow_sign_up = false
+;allow_sign_up = true
 ;client_id = some_client_id
 ;client_secret = some_client_secret
 ;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
@@ -218,7 +244,8 @@
 #################################### Generic OAuth ##########################
 [auth.generic_oauth]
 ;enabled = false
-;allow_sign_up = false
+;name = OAuth
+;allow_sign_up = true
 ;client_id = some_id
 ;client_secret = some_secret
 ;scopes = user:email,read:org
@@ -228,10 +255,10 @@
 ;team_ids =
 ;allowed_organizations =
 
-#################################### Grafana.net Auth ####################
-[auth.grafananet]
+#################################### Grafana.com Auth ####################
+[auth.grafana_com]
 ;enabled = false
-;allow_sign_up = false
+;allow_sign_up = true
 ;client_id = some_id
 ;client_secret = some_secret
 ;scopes = user:email
@@ -243,6 +270,8 @@
 ;header_name = X-WEBAUTH-USER
 ;header_property = username
 ;auto_sign_up = true
+;ldap_sync_ttl = 60
+;whitelist = 192.168.1.1, 192.168.2.1
 
 #################################### Basic Auth ##########################
 [auth.basic]
@@ -259,11 +288,15 @@
 ;enabled = false
 ;host = localhost:25
 ;user =
+# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
 ;password =
 ;cert_file =
 ;key_file =
 ;skip_verify = false
 ;from_address = admin@grafana.localhost
+;from_name = Grafana
+# EHLO identity in SMTP dialog (defaults to instance_name)
+;ehlo_identity = dashboard.example.com
 
 [emails]
 ;welcome_email_on_sign_up = false
@@ -272,9 +305,9 @@
 [log]
 # Either "console", "file", "syslog". Default is console and  file
 # Use space to separate multiple modes, e.g. "console file"
-;mode = console, file
+;mode = console file
 
-# Either "trace", "debug", "info", "warn", "error", "critical", default is "info"
+# Either "debug", "info", "warn", "error", "critical", default is "info"
 ;level = info
 
 # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
@@ -327,35 +360,16 @@
 ;tag =
 
 
-#################################### AMQP Event Publisher ##########################
-[event_publisher]
-;enabled = false
-;rabbitmq_url = amqp://localhost/
-;exchange = grafana_events
-
 ;#################################### Dashboard JSON files ##########################
 [dashboards.json]
 ;enabled = false
 ;path = /var/lib/grafana/dashboards
 
-#################################### Alerting ######################################
-# docs about alerting can be found in /docs/sources/alerting/
-#              __.-/|
-#              \`o_O'
-#               =( )=  +----------------------------+
-#                 U|   | Alerting is still in alpha |
-#       /\  /\   / |   +----------------------------+
-#      ) /^\) ^\/ _)\     |
-#      )   /^\/   _) \    |
-#      )   _ /  / _)  \___|_
-#  /\  )/\/ ||  | )_)\___,|))
-# <  >      |(,,) )__)    |
-#  ||      /    \)___)\
-#  | \____(      )___) )____
-#   \______(_______;;;)__;;;)
-
+#################################### Alerting ############################
 [alerting]
-# Makes it possible to turn off alert rule execution.
+# Disable alerting engine & UI features
+;enabled = true
+# Makes it possible to turn off alert rule execution but alerting UI is visible
 ;execute_alerts = true
 
 #################################### Internal Grafana Metrics ##########################
@@ -373,23 +387,47 @@
 ;address =
 ;prefix = prod.grafana.%(instance_name)s.
 
-#################################### Internal Grafana Metrics ##########################
-# Url used to to import dashboards directly from Grafana.net
-[grafana_net]
-;url = https://grafana.net
+#################################### Distributed tracing ############
+[tracing.jaeger]
+# Enable by setting the address sending traces to jaeger (ex localhost:6831)
+;address = localhost:6831
+# Tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
+;always_included_tag = tag1:value1
+# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
+;sampler_type = const
+# jaeger samplerconfig param
+# for "const" sampler, 0 or 1 for always false/true respectively
+# for "probabilistic" sampler, a probability between 0 and 1
+# for "rateLimiting" sampler, the number of spans per second
+# for "remote" sampler, param is the same as for "probabilistic"
+# and indicates the initial sampling rate before the actual one
+# is received from the mothership
+;sampler_param = 1
+
+#################################### Grafana.com integration  ##########################
+# Url used to to import dashboards directly from Grafana.com
+[grafana_com]
+;url = https://grafana.com
 
 #################################### External image storage ##########################
 [external_image_storage]
 # Used for uploading images to public servers so they can be included in slack/email messages.
-# you can choose between (s3, webdav)
+# you can choose between (s3, webdav, gcs)
 ;provider =
 
 [external_image_storage.s3]
-;bucket_url =
+;bucket =
+;region =
+;path =
 ;access_key =
 ;secret_key =
 
 [external_image_storage.webdav]
 ;url =
+;public_url =
 ;username =
 ;password =
+
+[external_image_storage.gcs]
+;key_file =
+;bucket =

+ 11 - 0
docker/blocks/collectd/docker-compose.yaml

@@ -0,0 +1,11 @@
+  collectd:
+    build: blocks/collectd
+    environment:
+      HOST_NAME: myserver
+      GRAPHITE_HOST: graphite
+      GRAPHITE_PORT: 2003
+      GRAPHITE_PREFIX: collectd.
+      REPORT_BY_CPU: 'false'
+      COLLECT_INTERVAL: 10
+    links:
+      - graphite

+ 0 - 11
docker/blocks/collectd/fig

@@ -1,11 +0,0 @@
-collectd:
-  build: blocks/collectd
-  environment:
-    HOST_NAME: myserver
-    GRAPHITE_HOST: graphite
-    GRAPHITE_PORT: 2003
-    GRAPHITE_PREFIX: collectd.
-    REPORT_BY_CPU: 'false'
-    COLLECT_INTERVAL: 10
-  links:
-    - graphite

+ 8 - 0
docker/blocks/elastic/docker-compose.yaml

@@ -0,0 +1,8 @@
+  elasticsearch:
+    image: elasticsearch:2.4.1
+    command: elasticsearch -Des.network.host=0.0.0.0
+    ports:
+      - "9200:9200"
+      - "9300:9300"
+    volumes:
+      - ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

+ 0 - 8
docker/blocks/elastic/fig

@@ -1,8 +0,0 @@
-elasticsearch:
-  image: elasticsearch:latest
-  command: elasticsearch -Des.network.host=0.0.0.0
-  ports:
-    - "9200:9200"
-    - "9300:9300"
-  volumes:
-    - ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

+ 8 - 0
docker/blocks/elastic1/docker-compose.yaml

@@ -0,0 +1,8 @@
+  elasticsearch1:
+    image: elasticsearch:1.7.6
+    command: elasticsearch -Des.network.host=0.0.0.0
+    ports:
+      - "11200:9200"
+      - "11300:9300"
+    volumes:
+      - ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

+ 2 - 0
docker/blocks/elastic1/elasticsearch.yml

@@ -0,0 +1,2 @@
+script.inline: on
+script.indexed: on

+ 8 - 0
docker/blocks/elastic5/docker-compose.yaml

@@ -0,0 +1,8 @@
+# You need to run 'sysctl -w vm.max_map_count=262144' on the host machine
+
+  elasticsearch5:
+    image: elasticsearch:5
+    command: elasticsearch
+    ports:
+      - "10200:9200"
+      - "10300:9300"

+ 2 - 0
docker/blocks/elastic5/elasticsearch.yml

@@ -0,0 +1,2 @@
+script.inline: on
+script.indexed: on

+ 2 - 0
docker/blocks/graphite/Dockerfile

@@ -32,6 +32,7 @@ add ./files/my_htpasswd /etc/nginx/.htpasswd
 # Add system service config
 add ./files/nginx.conf /etc/nginx/nginx.conf
 add ./files/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+
 # Nginx
 #
 # graphite
@@ -39,6 +40,7 @@ expose  80
 
 # Carbon line receiver port
 expose  2003
+
 # Carbon cache query port
 expose  7002
 

+ 16 - 0
docker/blocks/graphite/docker-compose.yaml

@@ -0,0 +1,16 @@
+  graphite:
+    build: blocks/graphite
+    ports:
+      - "8080:80"
+      - "2003:2003"
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - /etc/timezone:/etc/timezone:ro
+
+  fake-graphite-data:
+    image: grafana/fake-data-gen
+    network_mode: bridge
+    environment:
+      FD_DATASOURCE: graphite
+      FD_PORT: 2003
+

+ 0 - 17
docker/blocks/graphite/fig

@@ -1,17 +0,0 @@
-graphite:
-  build: blocks/graphite
-  ports:
-    - "8080:80"
-    - "2003:2003"
-  volumes:
-    - /var/docker/gfdev/graphite:/opt/graphite/storage/whisper
-    - /etc/localtime:/etc/localtime:ro
-    - /etc/timezone:/etc/timezone:ro
-
-fake-graphite-data:
-  image: grafana/fake-data-gen
-  net: bridge
-  environment:
-    FD_DATASOURCE: graphite
-    FD_PORT: 2003
-

+ 93 - 0
docker/blocks/graphite1/Dockerfile

@@ -0,0 +1,93 @@
+FROM phusion/baseimage:0.9.22
+MAINTAINER Denys Zhdanov <denis.zhdanov@gmail.com>
+
+RUN apt-get -y update \
+  && apt-get -y upgrade \
+  && apt-get -y --force-yes install vim \
+  nginx \
+  python-dev \
+  python-flup \
+  python-pip \
+  python-ldap \
+  expect \
+  git \
+  memcached \
+  sqlite3 \
+  libffi-dev \
+  libcairo2 \
+  libcairo2-dev \
+  python-cairo \
+  python-rrdtool \
+  pkg-config \
+  nodejs \
+  && rm -rf /var/lib/apt/lists/*
+
+# fix python dependencies (LTS Django and newer memcached/txAMQP)
+RUN pip install django==1.8.18 \
+  python-memcached==1.53 \
+  txAMQP==0.6.2 \
+  && pip install --upgrade pip
+
+# install whisper
+RUN git clone -b 1.0.2 --depth 1 https://github.com/graphite-project/whisper.git /usr/local/src/whisper
+WORKDIR /usr/local/src/whisper
+RUN python ./setup.py install
+
+# install carbon
+RUN git clone -b 1.0.2 --depth 1 https://github.com/graphite-project/carbon.git /usr/local/src/carbon
+WORKDIR /usr/local/src/carbon
+RUN pip install -r requirements.txt \
+  && python ./setup.py install
+
+# install graphite
+RUN git clone -b 1.0.2 --depth 1 https://github.com/graphite-project/graphite-web.git /usr/local/src/graphite-web
+WORKDIR /usr/local/src/graphite-web
+RUN pip install -r requirements.txt \
+  && python ./setup.py install
+ADD conf/opt/graphite/conf/*.conf /opt/graphite/conf/
+ADD conf/opt/graphite/webapp/graphite/local_settings.py /opt/graphite/webapp/graphite/local_settings.py
+ADD conf/opt/graphite/webapp/graphite/app_settings.py /opt/graphite/webapp/graphite/app_settings.py
+WORKDIR /opt/graphite/webapp
+RUN mkdir -p /var/log/graphite/ \
+  && PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic --noinput --settings=graphite.settings
+
+# install statsd
+RUN git clone -b v0.7.2 https://github.com/etsy/statsd.git /opt/statsd
+ADD conf/opt/statsd/config.js /opt/statsd/config.js
+
+# config nginx
+RUN rm /etc/nginx/sites-enabled/default
+ADD conf/etc/nginx/nginx.conf /etc/nginx/nginx.conf
+ADD conf/etc/nginx/sites-enabled/graphite-statsd.conf /etc/nginx/sites-enabled/graphite-statsd.conf
+
+# init django admin
+ADD conf/usr/local/bin/django_admin_init.exp /usr/local/bin/django_admin_init.exp
+ADD conf/usr/local/bin/manage.sh /usr/local/bin/manage.sh
+RUN chmod +x /usr/local/bin/manage.sh \
+  && /usr/local/bin/django_admin_init.exp
+
+# logging support
+RUN mkdir -p /var/log/carbon /var/log/graphite /var/log/nginx
+ADD conf/etc/logrotate.d/graphite-statsd /etc/logrotate.d/graphite-statsd
+
+# daemons
+ADD conf/etc/service/carbon/run /etc/service/carbon/run
+ADD conf/etc/service/carbon-aggregator/run /etc/service/carbon-aggregator/run
+ADD conf/etc/service/graphite/run /etc/service/graphite/run
+ADD conf/etc/service/statsd/run /etc/service/statsd/run
+ADD conf/etc/service/nginx/run /etc/service/nginx/run
+
+# default conf setup
+ADD conf /etc/graphite-statsd/conf
+ADD conf/etc/my_init.d/01_conf_init.sh /etc/my_init.d/01_conf_init.sh
+
+# cleanup
+RUN apt-get clean\
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# defaults
+EXPOSE 80 2003-2004 2023-2024 8125/udp 8126
+VOLUME ["/opt/graphite/conf", "/opt/graphite/storage", "/etc/nginx", "/opt/statsd", "/etc/logrotate.d", "/var/log"]
+WORKDIR /
+ENV HOME /root
+CMD ["/sbin/my_init"]

+ 11 - 0
docker/blocks/graphite1/conf/etc/logrotate.d/graphite-statsd

@@ -0,0 +1,11 @@
+/var/log/*.log /var/log/*/*.log {
+  weekly
+  size 50M
+  missingok
+  rotate 10
+  compress
+  delaycompress
+  notifempty
+  copytruncate
+  su root syslog
+}

+ 36 - 0
docker/blocks/graphite1/conf/etc/my_init.d/01_conf_init.sh

@@ -0,0 +1,36 @@
+#!/bin/bash
+
+conf_dir=/etc/graphite-statsd/conf
+
+# auto setup graphite with default configs if /opt/graphite is missing
+# needed for the use case when a docker host volume is mounted at an of the following:
+#  - /opt/graphite
+#  - /opt/graphite/conf
+#  - /opt/graphite/webapp/graphite
+graphite_dir_contents=$(find /opt/graphite -mindepth 1 -print -quit)
+graphite_conf_dir_contents=$(find /opt/graphite/conf -mindepth 1 -print -quit)
+graphite_webapp_dir_contents=$(find /opt/graphite/webapp/graphite -mindepth 1 -print -quit)
+graphite_storage_dir_contents=$(find /opt/graphite/storage -mindepth 1 -print -quit)
+if [[ -z $graphite_dir_contents ]]; then
+  git clone -b 1.0.2 --depth 1 https://github.com/graphite-project/graphite-web.git /usr/local/src/graphite-web
+  cd /usr/local/src/graphite-web && python ./setup.py install
+fi
+if [[ -z $graphite_storage_dir_contents ]]; then
+  /usr/local/bin/django_admin_init.exp
+fi
+if [[ -z $graphite_conf_dir_contents ]]; then
+  cp -R $conf_dir/opt/graphite/conf/*.conf /opt/graphite/conf/
+fi
+if [[ -z $graphite_webapp_dir_contents ]]; then
+  cp $conf_dir/opt/graphite/webapp/graphite/local_settings.py /opt/graphite/webapp/graphite/local_settings.py
+fi
+
+# auto setup statsd with default config if /opt/statsd is missing
+# needed for the use case when a docker host volume is mounted at an of the following:
+#  - /opt/statsd
+statsd_dir_contents=$(find /opt/statsd -mindepth 1 -print -quit)
+if [[ -z $statsd_dir_contents ]]; then
+  git clone -b v0.7.2 https://github.com/etsy/statsd.git /opt/statsd
+  cp $conf_dir/opt/statsd/config.js /opt/statsd/config.js
+fi
+

+ 96 - 0
docker/blocks/graphite1/conf/etc/nginx/nginx.conf

@@ -0,0 +1,96 @@
+user www-data;
+worker_processes 4;
+pid /run/nginx.pid;
+daemon off;
+
+events {
+	worker_connections 768;
+	# multi_accept on;
+}
+
+http {
+
+	##
+	# Basic Settings
+	##
+
+	sendfile on;
+	tcp_nopush on;
+	tcp_nodelay on;
+	keepalive_timeout 65;
+	types_hash_max_size 2048;
+	# server_tokens off;
+
+	# server_names_hash_bucket_size 64;
+	# server_name_in_redirect off;
+
+	include /etc/nginx/mime.types;
+	default_type application/octet-stream;
+
+	##
+	# Logging Settings
+	##
+
+	access_log /var/log/nginx/access.log;
+	error_log /var/log/nginx/error.log;
+
+	##
+	# Gzip Settings
+	##
+
+	gzip on;
+	gzip_disable "msie6";
+
+	# gzip_vary on;
+	# gzip_proxied any;
+	# gzip_comp_level 6;
+	# gzip_buffers 16 8k;
+	# gzip_http_version 1.1;
+	# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
+
+	##
+	# nginx-naxsi config
+	##
+	# Uncomment it if you installed nginx-naxsi
+	##
+
+	#include /etc/nginx/naxsi_core.rules;
+
+	##
+	# nginx-passenger config
+	##
+	# Uncomment it if you installed nginx-passenger
+	##
+
+	#passenger_root /usr;
+	#passenger_ruby /usr/bin/ruby;
+
+	##
+	# Virtual Host Configs
+	##
+
+	include /etc/nginx/conf.d/*.conf;
+	include /etc/nginx/sites-enabled/*;
+}
+
+
+#mail {
+#	# See sample authentication script at:
+#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
+#
+#	# auth_http localhost/auth.php;
+#	# pop3_capabilities "TOP" "USER";
+#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
+#
+#	server {
+#		listen     localhost:110;
+#		protocol   pop3;
+#		proxy      on;
+#	}
+#
+#	server {
+#		listen     localhost:143;
+#		protocol   imap;
+#		proxy      on;
+#	}
+#}

+ 31 - 0
docker/blocks/graphite1/conf/etc/nginx/sites-enabled/graphite-statsd.conf

@@ -0,0 +1,31 @@
+server {
+  listen 80;
+  root /opt/graphite/static;
+  index index.html;
+
+  location /media {
+    # django admin static files
+    alias /usr/local/lib/python2.7/dist-packages/django/contrib/admin/media/;
+  }
+
+  location /admin/auth/admin {
+    alias /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin;
+  }
+
+  location /admin/auth/user/admin {
+    alias /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin;
+  }
+
+  location / {
+    proxy_pass http://localhost:8080;
+    proxy_set_header  Host      $host;
+    proxy_set_header  X-Real-IP $remote_addr;
+    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
+
+    add_header 'Access-Control-Allow-Origin' '*';
+    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
+    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
+    add_header 'Access-Control-Allow-Credentials' 'true';
+  }
+
+}

+ 4 - 0
docker/blocks/graphite1/conf/etc/service/carbon-aggregator/run

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+rm -f /opt/graphite/storage/carbon-aggregator-a.pid
+exec /usr/bin/python /opt/graphite/bin/carbon-aggregator.py start --debug 2>&1 >> /var/log/carbon-aggregator.log

+ 4 - 0
docker/blocks/graphite1/conf/etc/service/carbon/run

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+rm -f /opt/graphite/storage/carbon-cache-a.pid
+exec /usr/bin/python /opt/graphite/bin/carbon-cache.py start --debug 2>&1 >> /var/log/carbon.log

+ 3 - 0
docker/blocks/graphite1/conf/etc/service/graphite/run

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+export PYTHONPATH=/opt/graphite/webapp && exec /usr/local/bin/gunicorn wsgi --workers=4 --bind=127.0.0.1:8080 --log-file=/var/log/gunicorn.log --preload --pythonpath=/opt/graphite/webapp/graphite

+ 4 - 0
docker/blocks/graphite1/conf/etc/service/nginx/run

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+mkdir -p /var/log/nginx
+exec /usr/sbin/nginx -c /etc/nginx/nginx.conf

+ 4 - 0
docker/blocks/graphite1/conf/etc/service/statsd/run

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+exec /usr/bin/nodejs /opt/statsd/stats.js /opt/statsd/config.js >> /var/log/statsd.log 2>&1
+

+ 35 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/aggregation-rules.conf

@@ -0,0 +1,35 @@
+# The form of each line in this file should be as follows:
+#
+#   output_template (frequency) = method input_pattern
+#
+# This will capture any received metrics that match 'input_pattern'
+# for calculating an aggregate metric. The calculation will occur
+# every 'frequency' seconds and the 'method' can specify 'sum' or
+# 'avg'. The name of the aggregate metric will be derived from
+# 'output_template' filling in any captured fields from 'input_pattern'.
+#
+# For example, if you're metric naming scheme is:
+#
+#   <env>.applications.<app>.<server>.<metric>
+#
+# You could configure some aggregations like so:
+#
+#   <env>.applications.<app>.all.requests (60) = sum <env>.applications.<app>.*.requests
+#   <env>.applications.<app>.all.latency (60) = avg <env>.applications.<app>.*.latency
+#
+# As an example, if the following metrics are received:
+#
+#   prod.applications.apache.www01.requests
+#   prod.applications.apache.www01.requests
+#
+# They would all go into the same aggregation buffer and after 60 seconds the
+# aggregate metric 'prod.applications.apache.all.requests' would be calculated
+# by summing their values.
+#
+# Template components such as <env> will match everything up to the next dot.
+# To match metric multiple components including the dots, use <<metric>> in the
+# input template:
+#
+#   <env>.applications.<app>.all.<app_metric> (60) = sum <env>.applications.<app>.*.<<app_metric>>
+#
+# Note that any time this file is modified, it will be re-read automatically.

+ 5 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/blacklist.conf

@@ -0,0 +1,5 @@
+# This file takes a single regular expression per line
+# If USE_WHITELIST is set to True in carbon.conf, any metrics received which
+# match one of these expressions will be dropped
+# This file is reloaded automatically when changes are made
+^some\.noisy\.metric\.prefix\..*

+ 75 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/carbon.amqp.conf

@@ -0,0 +1,75 @@
+# This is a configuration file with AMQP enabled
+
+[cache]
+LOCAL_DATA_DIR =
+
+# Specify the user to drop privileges to
+# If this is blank carbon runs as the user that invokes it
+# This user must have write access to the local data directory
+USER =
+
+# Limit the size of the cache to avoid swapping or becoming CPU bound.
+# Sorts and serving cache queries gets more expensive as the cache grows.
+# Use the value "inf" (infinity) for an unlimited cache size.
+MAX_CACHE_SIZE = inf
+
+# Limits the number of whisper update_many() calls per second, which effectively
+# means the number of write requests sent to the disk. This is intended to
+# prevent over-utilizing the disk and thus starving the rest of the system.
+# When the rate of required updates exceeds this, then carbon's caching will
+# take effect and increase the overall throughput accordingly.
+MAX_UPDATES_PER_SECOND = 1000
+
+# Softly limits the number of whisper files that get created each minute.
+# Setting this value low (like at 50) is a good way to ensure your graphite
+# system will not be adversely impacted when a bunch of new metrics are
+# sent to it. The trade off is that it will take much longer for those metrics'
+# database files to all get created and thus longer until the data becomes usable.
+# Setting this value high (like "inf" for infinity) will cause graphite to create
+# the files quickly but at the risk of slowing I/O down considerably for a while.
+MAX_CREATES_PER_MINUTE = inf
+
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2003
+
+UDP_RECEIVER_INTERFACE = 0.0.0.0
+UDP_RECEIVER_PORT = 2003
+
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2004
+
+CACHE_QUERY_INTERFACE = 0.0.0.0
+CACHE_QUERY_PORT = 7002
+
+# Enable AMQP if you want to receve metrics using you amqp broker
+ENABLE_AMQP = True
+
+# Verbose means a line will be logged for every metric received
+# useful for testing
+AMQP_VERBOSE = True
+
+# your credentials for the amqp server
+# AMQP_USER = guest
+# AMQP_PASSWORD = guest
+
+# the network settings for the amqp server
+# AMQP_HOST = localhost
+# AMQP_PORT = 5672
+
+# if you want to include the metric name as part of the message body
+# instead of as the routing key, set this to True
+# AMQP_METRIC_NAME_IN_BODY = False
+
+# NOTE: you cannot run both a cache and a relay on the same server
+# with the default configuration, you have to specify a distinict
+# interfaces and ports for the listeners.
+
+[relay]
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2003
+
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2004
+
+CACHE_SERVERS = server1, server2, server3
+MAX_QUEUE_SIZE = 10000

+ 359 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/carbon.conf

@@ -0,0 +1,359 @@
+[cache]
+# Configure carbon directories.
+#
+# OS environment variables can be used to tell carbon where graphite is
+# installed, where to read configuration from and where to write data.
+#
+#   GRAPHITE_ROOT        - Root directory of the graphite installation.
+#                          Defaults to ../
+#   GRAPHITE_CONF_DIR    - Configuration directory (where this file lives).
+#                          Defaults to $GRAPHITE_ROOT/conf/
+#   GRAPHITE_STORAGE_DIR - Storage directory for whipser/rrd/log/pid files.
+#                          Defaults to $GRAPHITE_ROOT/storage/
+#
+# To change other directory paths, add settings to this file. The following
+# configuration variables are available with these default values:
+#
+#   STORAGE_DIR    = $GRAPHITE_STORAGE_DIR
+#   LOCAL_DATA_DIR = STORAGE_DIR/whisper/
+#   WHITELISTS_DIR = STORAGE_DIR/lists/
+#   CONF_DIR       = STORAGE_DIR/conf/
+#   LOG_DIR        = STORAGE_DIR/log/
+#   PID_DIR        = STORAGE_DIR/
+#
+# For FHS style directory structures, use:
+#
+#   STORAGE_DIR    = /var/lib/carbon/
+#   CONF_DIR       = /etc/carbon/
+#   LOG_DIR        = /var/log/carbon/
+#   PID_DIR        = /var/run/
+#
+#LOCAL_DATA_DIR = /opt/graphite/storage/whisper/
+
+# Enable daily log rotation. If disabled, a kill -HUP can be used after a manual rotate
+ENABLE_LOGROTATION = True
+
+# Specify the user to drop privileges to
+# If this is blank carbon runs as the user that invokes it
+# This user must have write access to the local data directory
+USER =
+#
+# NOTE: The above settings must be set under [relay] and [aggregator]
+#       to take effect for those daemons as well
+
+# Limit the size of the cache to avoid swapping or becoming CPU bound.
+# Sorts and serving cache queries gets more expensive as the cache grows.
+# Use the value "inf" (infinity) for an unlimited cache size.
+MAX_CACHE_SIZE = inf
+
+# Limits the number of whisper update_many() calls per second, which effectively
+# means the number of write requests sent to the disk. This is intended to
+# prevent over-utilizing the disk and thus starving the rest of the system.
+# When the rate of required updates exceeds this, then carbon's caching will
+# take effect and increase the overall throughput accordingly.
+MAX_UPDATES_PER_SECOND = 500
+
+# If defined, this changes the MAX_UPDATES_PER_SECOND in Carbon when a
+# stop/shutdown is initiated.  This helps when MAX_UPDATES_PER_SECOND is
+# relatively low and carbon has cached a lot of updates; it enables the carbon
+# daemon to shutdown more quickly.
+# MAX_UPDATES_PER_SECOND_ON_SHUTDOWN = 1000
+
+# Softly limits the number of whisper files that get created each minute.
+# Setting this value low (like at 50) is a good way to ensure your graphite
+# system will not be adversely impacted when a bunch of new metrics are
+# sent to it. The trade off is that it will take much longer for those metrics'
+# database files to all get created and thus longer until the data becomes usable.
+# Setting this value high (like "inf" for infinity) will cause graphite to create
+# the files quickly but at the risk of slowing I/O down considerably for a while.
+MAX_CREATES_PER_MINUTE = 50
+
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2003
+
+# Set this to True to enable the UDP listener. By default this is off
+# because it is very common to run multiple carbon daemons and managing
+# another (rarely used) port for every carbon instance is not fun.
+ENABLE_UDP_LISTENER = False
+UDP_RECEIVER_INTERFACE = 0.0.0.0
+UDP_RECEIVER_PORT = 2003
+
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2004
+
+# Set to false to disable logging of successful connections
+LOG_LISTENER_CONNECTIONS = True
+
+# Per security concerns outlined in Bug #817247 the pickle receiver
+# will use a more secure and slightly less efficient unpickler.
+# Set this to True to revert to the old-fashioned insecure unpickler.
+USE_INSECURE_UNPICKLER = False
+
+CACHE_QUERY_INTERFACE = 0.0.0.0
+CACHE_QUERY_PORT = 7002
+
+# Set this to False to drop datapoints received after the cache
+# reaches MAX_CACHE_SIZE. If this is True (the default) then sockets
+# over which metrics are received will temporarily stop accepting
+# data until the cache size falls below 95% MAX_CACHE_SIZE.
+USE_FLOW_CONTROL = True
+
+# By default, carbon-cache will log every whisper update and cache hit. This can be excessive and
+# degrade performance if logging on the same volume as the whisper data is stored.
+LOG_UPDATES = False
+LOG_CACHE_HITS = False
+LOG_CACHE_QUEUE_SORTS = True
+
+# The thread that writes metrics to disk can use on of the following strategies
+# determining the order in which metrics are removed from cache and flushed to
+# disk. The default option preserves the same behavior as has been historically
+# available in version 0.9.10.
+#
+# sorted - All metrics in the cache will be counted and an ordered list of
+# them will be sorted according to the number of datapoints in the cache at the
+# moment of the list's creation. Metrics will then be flushed from the cache to
+# disk in that order.
+#
+# max - The writer thread will always pop and flush the metric from cache
+# that has the most datapoints. This will give a strong flush preference to
+# frequently updated metrics and will also reduce random file-io. Infrequently
+# updated metrics may only ever be persisted to disk at daemon shutdown if
+# there are a large number of metrics which receive very frequent updates OR if
+# disk i/o is very slow.
+#
+# naive - Metrics will be flushed from the cache to disk in an unordered
+# fashion. This strategy may be desirable in situations where the storage for
+# whisper files is solid state, CPU resources are very limited or deference to
+# the OS's i/o scheduler is expected to compensate for the random write
+# pattern.
+#
+CACHE_WRITE_STRATEGY = sorted
+
+# On some systems it is desirable for whisper to write synchronously.
+# Set this option to True if you'd like to try this. Basically it will
+# shift the onus of buffering writes from the kernel into carbon's cache.
+WHISPER_AUTOFLUSH = False
+
+# By default new Whisper files are created pre-allocated with the data region
+# filled with zeros to prevent fragmentation and speed up contiguous reads and
+# writes (which are common). Enabling this option will cause Whisper to create
+# the file sparsely instead. Enabling this option may allow a large increase of
+# MAX_CREATES_PER_MINUTE but may have longer term performance implications
+# depending on the underlying storage configuration.
+# WHISPER_SPARSE_CREATE = False
+
+# Only beneficial on linux filesystems that support the fallocate system call.
+# It maintains the benefits of contiguous reads/writes, but with a potentially
+# much faster creation speed, by allowing the kernel to handle the block
+# allocation and zero-ing. Enabling this option may allow a large increase of
+# MAX_CREATES_PER_MINUTE. If enabled on an OS or filesystem that is unsupported
+# this option will gracefully fallback to standard POSIX file access methods.
+WHISPER_FALLOCATE_CREATE = True
+
+# Enabling this option will cause Whisper to lock each Whisper file it writes
+# to with an exclusive lock (LOCK_EX, see: man 2 flock). This is useful when
+# multiple carbon-cache daemons are writing to the same files
+# WHISPER_LOCK_WRITES = False
+
+# Set this to True to enable whitelisting and blacklisting of metrics in
+# CONF_DIR/whitelist and CONF_DIR/blacklist. If the whitelist is missing or
+# empty, all metrics will pass through
+# USE_WHITELIST = False
+
+# By default, carbon itself will log statistics (such as a count,
+# metricsReceived) with the top level prefix of 'carbon' at an interval of 60
+# seconds. Set CARBON_METRIC_INTERVAL to 0 to disable instrumentation
+# CARBON_METRIC_PREFIX = carbon
+# CARBON_METRIC_INTERVAL = 60
+
+# Enable AMQP if you want to receve metrics using an amqp broker
+# ENABLE_AMQP = False
+
+# Verbose means a line will be logged for every metric received
+# useful for testing
+# AMQP_VERBOSE = False
+
+# AMQP_HOST = localhost
+# AMQP_PORT = 5672
+# AMQP_VHOST = /
+# AMQP_USER = guest
+# AMQP_PASSWORD = guest
+# AMQP_EXCHANGE = graphite
+# AMQP_METRIC_NAME_IN_BODY = False
+
+# The manhole interface allows you to SSH into the carbon daemon
+# and get a python interpreter. BE CAREFUL WITH THIS! If you do
+# something like time.sleep() in the interpreter, the whole process
+# will sleep! This is *extremely* helpful in debugging, assuming
+# you are familiar with the code. If you are not, please don't
+# mess with this, you are asking for trouble :)
+#
+# ENABLE_MANHOLE = False
+# MANHOLE_INTERFACE = 127.0.0.1
+# MANHOLE_PORT = 7222
+# MANHOLE_USER = admin
+# MANHOLE_PUBLIC_KEY = ssh-rsa AAAAB3NzaC1yc2EAAAABiwAaAIEAoxN0sv/e4eZCPpi3N3KYvyzRaBaMeS2RsOQ/cDuKv11dlNzVeiyc3RFmCv5Rjwn/lQ79y0zyHxw67qLyhQ/kDzINc4cY41ivuQXm2tPmgvexdrBv5nsfEpjs3gLZfJnyvlcVyWK/lId8WUvEWSWHTzsbtmXAF2raJMdgLTbQ8wE=
+
+# Patterns for all of the metrics this machine will store. Read more at
+# http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol#Bindings
+#
+# Example: store all sales, linux servers, and utilization metrics
+# BIND_PATTERNS = sales.#, servers.linux.#, #.utilization
+#
+# Example: store everything
+# BIND_PATTERNS = #
+
+# To configure special settings for the carbon-cache instance 'b', uncomment this:
+#[cache:b]
+#LINE_RECEIVER_PORT = 2103
+#PICKLE_RECEIVER_PORT = 2104
+#CACHE_QUERY_PORT = 7102
+# and any other settings you want to customize, defaults are inherited
+# from [carbon] section.
+# You can then specify the --instance=b option to manage this instance
+
+
+
+[relay]
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2013
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2014
+
+# Set to false to disable logging of successful connections
+LOG_LISTENER_CONNECTIONS = True
+
+# Carbon-relay has several options for metric routing controlled by RELAY_METHOD
+#
+# Use relay-rules.conf to route metrics to destinations based on pattern rules
+#RELAY_METHOD = rules
+#
+# Use consistent-hashing for even distribution of metrics between destinations
+#RELAY_METHOD = consistent-hashing
+#
+# Use consistent-hashing but take into account an aggregation-rules.conf shared
+# by downstream carbon-aggregator daemons. This will ensure that all metrics
+# that map to a given aggregation rule are sent to the same carbon-aggregator
+# instance.
+# Enable this for carbon-relays that send to a group of carbon-aggregators
+#RELAY_METHOD = aggregated-consistent-hashing
+RELAY_METHOD = rules
+
+# If you use consistent-hashing you can add redundancy by replicating every
+# datapoint to more than one machine.
+REPLICATION_FACTOR = 1
+
+# This is a list of carbon daemons we will send any relayed or
+# generated metrics to. The default provided would send to a single
+# carbon-cache instance on the default port. However if you
+# use multiple carbon-cache instances then it would look like this:
+#
+# DESTINATIONS = 127.0.0.1:2004:a, 127.0.0.1:2104:b
+#
+# The general form is IP:PORT:INSTANCE where the :INSTANCE part is
+# optional and refers to the "None" instance if omitted.
+#
+# Note that if the destinations are all carbon-caches then this should
+# exactly match the webapp's CARBONLINK_HOSTS setting in terms of
+# instances listed (order matters!).
+#
+# If using RELAY_METHOD = rules, all destinations used in relay-rules.conf
+# must be defined in this list
+DESTINATIONS = 127.0.0.1:2004
+
+# This defines the maximum "message size" between carbon daemons.
+# You shouldn't need to tune this unless you really know what you're doing.
+MAX_DATAPOINTS_PER_MESSAGE = 500
+MAX_QUEUE_SIZE = 10000
+
+# Set this to False to drop datapoints when any send queue (sending datapoints
+# to a downstream carbon daemon) hits MAX_QUEUE_SIZE. If this is True (the
+# default) then sockets over which metrics are received will temporarily stop accepting
+# data until the send queues fall below 80% MAX_QUEUE_SIZE.
+USE_FLOW_CONTROL = True
+
+# Set this to True to enable whitelisting and blacklisting of metrics in
+# CONF_DIR/whitelist and CONF_DIR/blacklist. If the whitelist is missing or
+# empty, all metrics will pass through
+# USE_WHITELIST = False
+
+# By default, carbon itself will log statistics (such as a count,
+# metricsReceived) with the top level prefix of 'carbon' at an interval of 60
+# seconds. Set CARBON_METRIC_INTERVAL to 0 to disable instrumentation
+# CARBON_METRIC_PREFIX = carbon
+# CARBON_METRIC_INTERVAL = 60
+
+
+[aggregator]
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2023
+
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2024
+
+# Set to false to disable logging of successful connections
+LOG_LISTENER_CONNECTIONS = True
+
+# If set true, metric received will be forwarded to DESTINATIONS in addition to
+# the output of the aggregation rules. If set false the carbon-aggregator will
+# only ever send the output of aggregation.
+FORWARD_ALL = True
+
+# This is a list of carbon daemons we will send any relayed or
+# generated metrics to. The default provided would send to a single
+# carbon-cache instance on the default port. However if you
+# use multiple carbon-cache instances then it would look like this:
+#
+# DESTINATIONS = 127.0.0.1:2004:a, 127.0.0.1:2104:b
+#
+# The format is comma-delimited IP:PORT:INSTANCE where the :INSTANCE part is
+# optional and refers to the "None" instance if omitted.
+#
+# Note that if the destinations are all carbon-caches then this should
+# exactly match the webapp's CARBONLINK_HOSTS setting in terms of
+# instances listed (order matters!).
+DESTINATIONS = 127.0.0.1:2004
+
+# If you want to add redundancy to your data by replicating every
+# datapoint to more than one machine, increase this.
+REPLICATION_FACTOR = 1
+
+# This is the maximum number of datapoints that can be queued up
+# for a single destination. Once this limit is hit, we will
+# stop accepting new data if USE_FLOW_CONTROL is True, otherwise
+# we will drop any subsequently received datapoints.
+MAX_QUEUE_SIZE = 10000
+
+# Set this to False to drop datapoints when any send queue (sending datapoints
+# to a downstream carbon daemon) hits MAX_QUEUE_SIZE. If this is True (the
+# default) then sockets over which metrics are received will temporarily stop accepting
+# data until the send queues fall below 80% MAX_QUEUE_SIZE.
+USE_FLOW_CONTROL = True
+
+# This defines the maximum "message size" between carbon daemons.
+# You shouldn't need to tune this unless you really know what you're doing.
+MAX_DATAPOINTS_PER_MESSAGE = 500
+
+# This defines how many datapoints the aggregator remembers for
+# each metric. Aggregation only happens for datapoints that fall in
+# the past MAX_AGGREGATION_INTERVALS * intervalSize seconds.
+MAX_AGGREGATION_INTERVALS = 5
+
+# By default (WRITE_BACK_FREQUENCY = 0), carbon-aggregator will write back
+# aggregated data points once every rule.frequency seconds, on a per-rule basis.
+# Set this (WRITE_BACK_FREQUENCY = N) to write back all aggregated data points
+# every N seconds, independent of rule frequency. This is useful, for example,
+# to be able to query partially aggregated metrics from carbon-cache without
+# having to first wait rule.frequency seconds.
+# WRITE_BACK_FREQUENCY = 0
+
+# Set this to True to enable whitelisting and blacklisting of metrics in
+# CONF_DIR/whitelist and CONF_DIR/blacklist. If the whitelist is missing or
+# empty, all metrics will pass through
+# USE_WHITELIST = False
+
+# By default, carbon itself will log statistics (such as a count,
+# metricsReceived) with the top level prefix of 'carbon' at an interval of 60
+# seconds. Set CARBON_METRIC_INTERVAL to 0 to disable instrumentation
+# CARBON_METRIC_PREFIX = carbon
+# CARBON_METRIC_INTERVAL = 60

+ 57 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/dashboard.conf

@@ -0,0 +1,57 @@
+# This configuration file controls the behavior of the Dashboard UI, available
+# at http://my-graphite-server/dashboard/.
+#
+# This file must contain a [ui] section that defines values for all of the
+# following settings.
+[ui]
+default_graph_width = 400
+default_graph_height = 250
+automatic_variants = true
+refresh_interval = 60
+autocomplete_delay = 375
+merge_hover_delay = 750
+
+# You can set this 'default', 'white', or a custom theme name.
+# To create a custom theme, copy the dashboard-default.css file
+# to dashboard-myThemeName.css in the content/css directory and
+# modify it to your liking.
+theme = default
+
+[keyboard-shortcuts]
+toggle_toolbar = ctrl-z
+toggle_metrics_panel = ctrl-space
+erase_all_graphs = alt-x
+save_dashboard = alt-s
+completer_add_metrics = alt-enter
+completer_del_metrics = alt-backspace
+give_completer_focus = shift-space
+
+# These settings apply to the UI as a whole, all other sections in this file
+# pertain only to specific metric types.
+#
+# The dashboard presents only metrics that fall into specified naming schemes
+# defined in this file. This creates a simpler, more targetted view of the
+# data. The general form for defining a naming scheme is as follows:
+#
+#[Metric Type]
+#scheme = basis.path.<field1>.<field2>.<fieldN>
+#field1.label = Foo
+#field2.label = Bar
+#
+#
+# Where each <field> will be displayed as a dropdown box
+# in the UI and the remaining portion of the namespace
+# shown in the Metric Selector panel. The .label options set the labels
+# displayed for each dropdown.
+#
+# For example:
+#
+#[Sales]
+#scheme = sales.<channel>.<type>.<brand>
+#channel.label = Channel
+#type.label = Product Type
+#brand.label = Brand
+#
+# This defines a 'Sales' metric type that uses 3 dropdowns in the Context Selector
+# (the upper-left panel) while any deeper metrics (per-product counts or revenue, etc)
+# will be available in the Metric Selector (upper-right panel).

+ 38 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/graphTemplates.conf

@@ -0,0 +1,38 @@
+[default]
+background = black
+foreground = white
+majorLine = white
+minorLine = grey
+lineColors = blue,green,red,purple,brown,yellow,aqua,grey,magenta,pink,gold,rose
+fontName = Sans
+fontSize = 10
+fontBold = False
+fontItalic = False
+
+[noc]
+background = black
+foreground = white
+majorLine = white
+minorLine = grey
+lineColors = blue,green,red,yellow,purple,brown,aqua,grey,magenta,pink,gold,rose
+fontName = Sans
+fontSize = 10
+fontBold = False
+fontItalic = False
+
+[plain]
+background = white
+foreground = black
+minorLine = grey
+majorLine = rose
+
+[summary]
+background = black
+lineColors = #6666ff, #66ff66, #ff6666
+
+[alphas]
+background = white
+foreground = black
+majorLine = grey
+minorLine = rose
+lineColors = 00ff00aa,ff000077,00337799

+ 21 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/relay-rules.conf

@@ -0,0 +1,21 @@
+# Relay destination rules for carbon-relay. Entries are scanned in order,
+# and the first pattern a metric matches will cause processing to cease after sending
+# unless `continue` is set to true
+#
+#  [name]
+#  pattern = <regex>
+#  destinations = <list of destination addresses>
+#  continue = <boolean>  # default: False
+#
+#  name: Arbitrary unique name to identify the rule
+#  pattern: Regex pattern to match against the metric name
+#  destinations: Comma-separated list of destinations.
+#    ex: 127.0.0.1, 10.1.2.3:2004, 10.1.2.4:2004:a, myserver.mydomain.com
+#  continue: Continue processing rules if this rule matches (default: False)
+
+# You must have exactly one section with 'default = true'
+# Note that all destinations listed must also exist in carbon.conf
+# in the DESTINATIONS setting in the [relay] section
+[default]
+default = true
+destinations = 127.0.0.1:2004:a, 127.0.0.1:2104:b

+ 18 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/rewrite-rules.conf

@@ -0,0 +1,18 @@
+# This file defines regular expression patterns that can be used to
+# rewrite metric names in a search & replace fashion. It consists of two
+# sections, [pre] and [post]. The rules in the pre section are applied to
+# metric names as soon as they are received. The post rules are applied
+# after aggregation has taken place.
+#
+# The general form of each rule is as follows:
+#
+# regex-pattern = replacement-text
+#
+# For example:
+#
+# [post]
+# _sum$ =
+# _avg$ =
+#
+# These rules would strip off a suffix of _sum or _avg from any metric names
+# after aggregation.

+ 43 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/storage-aggregation.conf

@@ -0,0 +1,43 @@
+# Aggregation methods for whisper files. Entries are scanned in order,
+# and first match wins. This file is scanned for changes every 60 seconds
+#
+#  [name]
+#  pattern = <regex>
+#  xFilesFactor = <float between 0 and 1>
+#  aggregationMethod = <average|sum|last|max|min>
+#
+#  name: Arbitrary unique name for the rule
+#  pattern: Regex pattern to match against the metric name
+#  xFilesFactor: Ratio of valid data points required for aggregation to the next retention to occur
+#  aggregationMethod: function to apply to data points for aggregation
+#
+[min]
+pattern = \.lower$
+xFilesFactor = 0.1
+aggregationMethod = min
+
+[max]
+pattern = \.upper(_\d+)?$
+xFilesFactor = 0.1
+aggregationMethod = max
+
+[sum]
+pattern = \.sum$
+xFilesFactor = 0
+aggregationMethod = sum
+
+[count]
+pattern = \.count$
+xFilesFactor = 0
+aggregationMethod = sum
+
+[count_legacy]
+pattern = ^stats_counts.*
+xFilesFactor = 0
+aggregationMethod = sum
+
+[default_average]
+pattern = .*
+xFilesFactor = 0.3
+aggregationMethod = average
+

+ 17 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/storage-schemas.conf

@@ -0,0 +1,17 @@
+# Schema definitions for Whisper files. Entries are scanned in order,
+[carbon]
+pattern = ^carbon\..*
+retentions = 1m:31d,10m:1y,1h:5y
+
+[highres]
+pattern = ^highres.*
+retentions = 1s:1d,1m:7d
+
+[statsd]
+pattern = ^statsd.*
+retentions = 1m:7d,10m:1y
+
+[default]
+pattern = .*
+retentions = 10s:1d,1m:7d,10m:1y
+

+ 6 - 0
docker/blocks/graphite1/conf/opt/graphite/conf/whitelist.conf

@@ -0,0 +1,6 @@
+# This file takes a single regular expression per line
+# If USE_WHITELIST is set to True in carbon.conf, only metrics received which
+# match one of these expressions will be persisted. If this file is empty or
+# missing, all metrics will pass through.
+# This file is reloaded automatically when changes are made
+.*

+ 94 - 0
docker/blocks/graphite1/conf/opt/graphite/webapp/graphite/app_settings.py

@@ -0,0 +1,94 @@
+"""Copyright 2008 Orbitz WorldWide
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License."""
+
+# Django settings for graphite project.
+# DO NOT MODIFY THIS FILE DIRECTLY - use local_settings.py instead
+from os.path import dirname, join, abspath
+
+
+#Django settings below, do not touch!
+APPEND_SLASH = False
+TEMPLATE_DEBUG = False
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [
+            join(dirname( abspath(__file__) ), 'templates')
+        ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
+                # list if you haven't customized them:
+                'django.contrib.auth.context_processors.auth',
+                'django.template.context_processors.debug',
+                'django.template.context_processors.i18n',
+                'django.template.context_processors.media',
+                'django.template.context_processors.static',
+                'django.template.context_processors.tz',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+# Language code for this installation. All choices can be found here:
+# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
+# http://blogs.law.harvard.edu/tech/stories/storyReader$15
+LANGUAGE_CODE = 'en-us'
+
+# Absolute path to the directory that holds media.
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT.
+# Example: "http://media.lawrence.com"
+MEDIA_URL = ''
+
+MIDDLEWARE_CLASSES = (
+  'graphite.middleware.LogExceptionsMiddleware',
+  'django.middleware.common.CommonMiddleware',
+  'django.middleware.gzip.GZipMiddleware',
+  'django.contrib.sessions.middleware.SessionMiddleware',
+  'django.contrib.auth.middleware.AuthenticationMiddleware',
+  'django.contrib.messages.middleware.MessageMiddleware',
+)
+
+ROOT_URLCONF = 'graphite.urls'
+
+INSTALLED_APPS = (
+  'graphite.metrics',
+  'graphite.render',
+  'graphite.browser',
+  'graphite.composer',
+  'graphite.account',
+  'graphite.dashboard',
+  'graphite.whitelist',
+  'graphite.events',
+  'graphite.url_shortener',
+  'django.contrib.auth',
+  'django.contrib.sessions',
+  'django.contrib.admin',
+  'django.contrib.contenttypes',
+  'django.contrib.staticfiles',
+  'tagging',
+)
+
+AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend']
+
+GRAPHITE_WEB_APP_SETTINGS_LOADED = True
+
+STATIC_URL = '/static/'
+
+STATIC_ROOT = '/opt/graphite/static/'

+ 215 - 0
docker/blocks/graphite1/conf/opt/graphite/webapp/graphite/local_settings.py

@@ -0,0 +1,215 @@
+## Graphite local_settings.py
+# Edit this file to customize the default Graphite webapp settings
+#
+# Additional customizations to Django settings can be added to this file as well
+
+#####################################
+# General Configuration #
+#####################################
+# Set this to a long, random unique string to use as a secret key for this
+# install. This key is used for salting of hashes used in auth tokens,
+# CRSF middleware, cookie storage, etc. This should be set identically among
+# instances if used behind a load balancer.
+#SECRET_KEY = 'UNSAFE_DEFAULT'
+
+# In Django 1.5+ set this to the list of hosts your graphite instances is
+# accessible as. See:
+# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-ALLOWED_HOSTS
+#ALLOWED_HOSTS = [ '*' ]
+
+# Set your local timezone (Django's default is America/Chicago)
+# If your graphs appear to be offset by a couple hours then this probably
+# needs to be explicitly set to your local timezone.
+#TIME_ZONE = 'America/Los_Angeles'
+
+# Override this to provide documentation specific to your Graphite deployment
+#DOCUMENTATION_URL = "http://graphite.readthedocs.org/"
+
+# Logging
+#LOG_RENDERING_PERFORMANCE = True
+#LOG_CACHE_PERFORMANCE = True
+#LOG_METRIC_ACCESS = True
+
+# Enable full debug page display on exceptions (Internal Server Error pages)
+#DEBUG = True
+
+# If using RRD files and rrdcached, set to the address or socket of the daemon
+#FLUSHRRDCACHED = 'unix:/var/run/rrdcached.sock'
+
+# This lists the memcached servers that will be used by this webapp.
+# If you have a cluster of webapps you should ensure all of them
+# have the *exact* same value for this setting. That will maximize cache
+# efficiency. Setting MEMCACHE_HOSTS to be empty will turn off use of
+# memcached entirely.
+#
+# You should not use the loopback address (127.0.0.1) here if using clustering
+# as every webapp in the cluster should use the exact same values to prevent
+# unneeded cache misses. Set to [] to disable caching of images and fetched data
+#MEMCACHE_HOSTS = ['10.10.10.10:11211', '10.10.10.11:11211', '10.10.10.12:11211']
+#DEFAULT_CACHE_DURATION = 60 # Cache images and data for 1 minute
+
+
+#####################################
+# Filesystem Paths #
+#####################################
+# Change only GRAPHITE_ROOT if your install is merely shifted from /opt/graphite
+# to somewhere else
+#GRAPHITE_ROOT = '/opt/graphite'
+
+# Most installs done outside of a separate tree such as /opt/graphite will only
+# need to change these three settings. Note that the default settings for each
+# of these is relative to GRAPHITE_ROOT
+#CONF_DIR = '/opt/graphite/conf'
+#STORAGE_DIR = '/opt/graphite/storage'
+#CONTENT_DIR = '/opt/graphite/webapp/content'
+
+# To further or fully customize the paths, modify the following. Note that the
+# default settings for each of these are relative to CONF_DIR and STORAGE_DIR
+#
+## Webapp config files
+#DASHBOARD_CONF = '/opt/graphite/conf/dashboard.conf'
+#GRAPHTEMPLATES_CONF = '/opt/graphite/conf/graphTemplates.conf'
+
+## Data directories
+# NOTE: If any directory is unreadable in DATA_DIRS it will break metric browsing
+#WHISPER_DIR = '/opt/graphite/storage/whisper'
+#RRD_DIR = '/opt/graphite/storage/rrd'
+#DATA_DIRS = [WHISPER_DIR, RRD_DIR] # Default: set from the above variables
+#LOG_DIR = '/opt/graphite/storage/log/webapp'
+#INDEX_FILE = '/opt/graphite/storage/index'  # Search index file
+
+
+#####################################
+# Email Configuration #
+#####################################
+# This is used for emailing rendered Graphs
+# Default backend is SMTP
+#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+#EMAIL_HOST = 'localhost'
+#EMAIL_PORT = 25
+#EMAIL_HOST_USER = ''
+#EMAIL_HOST_PASSWORD = ''
+#EMAIL_USE_TLS = False
+# To drop emails on the floor, enable the Dummy backend:
+#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
+
+
+#####################################
+# Authentication Configuration #
+#####################################
+## LDAP / ActiveDirectory authentication setup
+#USE_LDAP_AUTH = True
+#LDAP_SERVER = "ldap.mycompany.com"
+#LDAP_PORT = 389
+#	OR
+#LDAP_URI = "ldaps://ldap.mycompany.com:636"
+#LDAP_SEARCH_BASE = "OU=users,DC=mycompany,DC=com"
+#LDAP_BASE_USER = "CN=some_readonly_account,DC=mycompany,DC=com"
+#LDAP_BASE_PASS = "readonly_account_password"
+#LDAP_USER_QUERY = "(username=%s)"  #For Active Directory use "(sAMAccountName=%s)"
+#
+# If you want to further customize the ldap connection options you should
+# directly use ldap.set_option to set the ldap module's global options.
+# For example:
+#
+#import ldap
+#ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
+#ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, "/etc/ssl/ca")
+#ldap.set_option(ldap.OPT_X_TLS_CERTFILE, "/etc/ssl/mycert.pem")
+#ldap.set_option(ldap.OPT_X_TLS_KEYFILE, "/etc/ssl/mykey.pem")
+# See http://www.python-ldap.org/ for further details on these options.
+
+## REMOTE_USER authentication. See: https://docs.djangoproject.com/en/dev/howto/auth-remote-user/
+#USE_REMOTE_USER_AUTHENTICATION = True
+
+# Override the URL for the login link (e.g. for django_openid_auth)
+#LOGIN_URL = '/account/login'
+
+
+##########################
+# Database Configuration #
+##########################
+# By default sqlite is used. If you cluster multiple webapps you will need
+# to setup an external database (such as MySQL) and configure all of the webapp
+# instances to use the same database. Note that this database is only used to store
+# Django models such as saved graphs, dashboards, user preferences, etc.
+# Metric data is not stored here.
+#
+# DO NOT FORGET TO RUN 'manage.py syncdb' AFTER SETTING UP A NEW DATABASE
+#
+# The following built-in database engines are available:
+#  django.db.backends.postgresql          # Removed in Django 1.4
+#  django.db.backends.postgresql_psycopg2
+#  django.db.backends.mysql
+#  django.db.backends.sqlite3
+#  django.db.backends.oracle
+#
+# The default is 'django.db.backends.sqlite3' with file 'graphite.db'
+# located in STORAGE_DIR
+#
+#DATABASES = {
+#    'default': {
+#        'NAME': '/opt/graphite/storage/graphite.db',
+#        'ENGINE': 'django.db.backends.sqlite3',
+#        'USER': '',
+#        'PASSWORD': '',
+#        'HOST': '',
+#        'PORT': ''
+#    }
+#}
+#
+
+
+#########################
+# Cluster Configuration #
+#########################
+# (To avoid excessive DNS lookups you want to stick to using IP addresses only in this entire section)
+#
+# This should list the IP address (and optionally port) of the webapp on each
+# remote server in the cluster. These servers must each have local access to
+# metric data. Note that the first server to return a match for a query will be
+# used.
+#CLUSTER_SERVERS = ["10.0.2.2:80", "10.0.2.3:80"]
+
+## These are timeout values (in seconds) for requests to remote webapps
+#REMOTE_STORE_FETCH_TIMEOUT = 6   # Timeout to fetch series data
+#REMOTE_STORE_FIND_TIMEOUT = 2.5  # Timeout for metric find requests
+#REMOTE_STORE_RETRY_DELAY = 60    # Time before retrying a failed remote webapp
+#REMOTE_FIND_CACHE_DURATION = 300 # Time to cache remote metric find results
+
+## Remote rendering settings
+# Set to True to enable rendering of Graphs on a remote webapp
+#REMOTE_RENDERING = True
+# List of IP (and optionally port) of the webapp on each remote server that
+# will be used for rendering. Note that each rendering host should have local
+# access to metric data or should have CLUSTER_SERVERS configured
+#RENDERING_HOSTS = []
+#REMOTE_RENDER_CONNECT_TIMEOUT = 1.0
+
+# If you are running multiple carbon-caches on this machine (typically behind a relay using
+# consistent hashing), you'll need to list the ip address, cache query port, and instance name of each carbon-cache
+# instance on the local machine (NOT every carbon-cache in the entire cluster). The default cache query port is 7002
+# and a common scheme is to use 7102 for instance b, 7202 for instance c, etc.
+#
+# You *should* use 127.0.0.1 here in most cases
+#CARBONLINK_HOSTS = ["127.0.0.1:7002:a", "127.0.0.1:7102:b", "127.0.0.1:7202:c"]
+#CARBONLINK_TIMEOUT = 1.0
+
+#####################################
+# Additional Django Settings #
+#####################################
+# Uncomment the following line for direct access to Django settings such as
+# MIDDLEWARE_CLASSES or APPS
+#from graphite.app_settings import *
+
+import os
+
+LOG_DIR = '/var/log/graphite'
+SECRET_KEY = '$(date +%s | sha256sum | base64 | head -c 64)'
+
+if (os.getenv("MEMCACHE_HOST") is not None):
+    MEMCACHE_HOSTS = os.getenv("MEMCACHE_HOST").split(",")
+
+if (os.getenv("DEFAULT_CACHE_DURATION") is not None):
+    DEFAULT_CACHE_DURATION = int(os.getenv("CACHE_DURATION"))
+

+ 6 - 0
docker/blocks/graphite1/conf/opt/statsd/config.js

@@ -0,0 +1,6 @@
+{
+  "graphiteHost": "127.0.0.1",
+  "graphitePort": 2003,
+  "port": 8125,
+  "flushInterval": 10000
+}

+ 26 - 0
docker/blocks/graphite1/conf/usr/local/bin/django_admin_init.exp

@@ -0,0 +1,26 @@
+#!/usr/bin/env expect
+
+set timeout -1
+spawn /usr/local/bin/manage.sh
+
+expect "Would you like to create one now" {
+  send "yes\r"
+}
+
+expect "Username" {
+  send "root\r"
+}
+
+expect "Email address:" {
+  send "root.graphite@mailinator.com\r"
+}
+
+expect "Password:" {
+  send "root\r"
+}
+
+expect "Password *:" {
+  send "root\r"
+}
+
+expect "Superuser created successfully"

+ 3 - 0
docker/blocks/graphite1/conf/usr/local/bin/manage.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+PYTHONPATH=/opt/graphite/webapp django-admin.py syncdb --settings=graphite.settings
+PYTHONPATH=/opt/graphite/webapp django-admin.py update_users --settings=graphite.settings

+ 16 - 0
docker/blocks/graphite1/docker-compose.yaml

@@ -0,0 +1,16 @@
+  graphite:
+    build: blocks/graphite1
+    ports:
+      - "8080:80"
+      - "2003:2003"
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - /etc/timezone:/etc/timezone:ro
+
+  fake-graphite-data:
+    image: grafana/fake-data-gen
+    network_mode: bridge
+    environment:
+      FD_DATASOURCE: graphite
+      FD_PORT: 2003
+

+ 76 - 0
docker/blocks/graphite1/files/carbon.conf

@@ -0,0 +1,76 @@
+[cache]
+LOCAL_DATA_DIR = /opt/graphite/storage/whisper/
+
+# Specify the user to drop privileges to
+# If this is blank carbon runs as the user that invokes it
+# This user must have write access to the local data directory
+USER =
+
+# Limit the size of the cache to avoid swapping or becoming CPU bound.
+# Sorts and serving cache queries gets more expensive as the cache grows.
+# Use the value "inf" (infinity) for an unlimited cache size.
+MAX_CACHE_SIZE = inf
+
+# Limits the number of whisper update_many() calls per second, which effectively
+# means the number of write requests sent to the disk. This is intended to
+# prevent over-utilizing the disk and thus starving the rest of the system.
+# When the rate of required updates exceeds this, then carbon's caching will
+# take effect and increase the overall throughput accordingly.
+MAX_UPDATES_PER_SECOND = 1000
+
+# Softly limits the number of whisper files that get created each minute.
+# Setting this value low (like at 50) is a good way to ensure your graphite
+# system will not be adversely impacted when a bunch of new metrics are
+# sent to it. The trade off is that it will take much longer for those metrics'
+# database files to all get created and thus longer until the data becomes usable.
+# Setting this value high (like "inf" for infinity) will cause graphite to create
+# the files quickly but at the risk of slowing I/O down considerably for a while.
+MAX_CREATES_PER_MINUTE = inf
+
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2003
+
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2004
+
+CACHE_QUERY_INTERFACE = 0.0.0.0
+CACHE_QUERY_PORT = 7002
+
+LOG_UPDATES = False
+
+# Enable AMQP if you want to receve metrics using an amqp broker
+# ENABLE_AMQP = False
+
+# Verbose means a line will be logged for every metric received
+# useful for testing
+# AMQP_VERBOSE = False
+
+# AMQP_HOST = localhost
+# AMQP_PORT = 5672
+# AMQP_VHOST = /
+# AMQP_USER = guest
+# AMQP_PASSWORD = guest
+# AMQP_EXCHANGE = graphite
+
+# Patterns for all of the metrics this machine will store. Read more at
+# http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol#Bindings
+#
+# Example: store all sales, linux servers, and utilization metrics
+# BIND_PATTERNS = sales.#, servers.linux.#, #.utilization
+#
+# Example: store everything
+# BIND_PATTERNS = #
+
+# NOTE: you cannot run both a cache and a relay on the same server
+# with the default configuration, you have to specify a distinict
+# interfaces and ports for the listeners.
+
+[relay]
+LINE_RECEIVER_INTERFACE = 0.0.0.0
+LINE_RECEIVER_PORT = 2003
+
+PICKLE_RECEIVER_INTERFACE = 0.0.0.0
+PICKLE_RECEIVER_PORT = 2004
+
+CACHE_SERVERS = server1, server2, server3
+MAX_QUEUE_SIZE = 10000

+ 102 - 0
docker/blocks/graphite1/files/events_views.py

@@ -0,0 +1,102 @@
+import datetime
+import time
+
+from django.utils.timezone import get_current_timezone
+from django.core.urlresolvers import get_script_prefix
+from django.http import HttpResponse
+from django.shortcuts import render_to_response, get_object_or_404
+from pytz import timezone
+
+from graphite.util import json
+from graphite.events import models
+from graphite.render.attime import parseATTime
+
+
+def to_timestamp(dt):
+    return time.mktime(dt.timetuple())
+
+
+class EventEncoder(json.JSONEncoder):
+    def default(self, obj):
+        if isinstance(obj, datetime.datetime):
+            return to_timestamp(obj)
+        return json.JSONEncoder.default(self, obj)
+
+
+def view_events(request):
+    if request.method == "GET":
+        context = { 'events' : fetch(request),
+            'slash' : get_script_prefix()
+        }
+        return render_to_response("events.html", context)
+    else:
+        return post_event(request)
+
+def detail(request, event_id):
+    e = get_object_or_404(models.Event, pk=event_id)
+    context = { 'event' : e,
+       'slash' : get_script_prefix()
+    }
+    return render_to_response("event.html", context)
+
+
+def post_event(request):
+    if request.method == 'POST':
+        event = json.loads(request.body)
+        assert isinstance(event, dict)
+
+        values = {}
+        values["what"] = event["what"]
+        values["tags"] = event.get("tags", None)
+        values["when"] = datetime.datetime.fromtimestamp(
+            event.get("when", time.time()))
+        if "data" in event:
+            values["data"] = event["data"]
+
+        e = models.Event(**values)
+        e.save()
+
+        return HttpResponse(status=200)
+    else:
+        return HttpResponse(status=405)
+
+def get_data(request):
+    if 'jsonp' in request.REQUEST:
+        response = HttpResponse(
+          "%s(%s)" % (request.REQUEST.get('jsonp'),
+              json.dumps(fetch(request), cls=EventEncoder)),
+          mimetype='text/javascript')
+    else:
+        response = HttpResponse(
+            json.dumps(fetch(request), cls=EventEncoder),
+            mimetype="application/json")
+    return response
+
+def fetch(request):
+    #XXX we need to move to USE_TZ=True to get rid of naive-time conversions
+    def make_naive(dt):
+      if 'tz' in request.GET:
+        tz = timezone(request.GET['tz'])
+      else:
+        tz = get_current_timezone()
+      local_dt = dt.astimezone(tz)
+      if hasattr(local_dt, 'normalize'):
+        local_dt = local_dt.normalize()
+      return local_dt.replace(tzinfo=None)
+
+    if request.GET.get("from", None) is not None:
+        time_from = make_naive(parseATTime(request.GET["from"]))
+    else:
+        time_from = datetime.datetime.fromtimestamp(0)
+
+    if request.GET.get("until", None) is not None:
+        time_until = make_naive(parseATTime(request.GET["until"]))
+    else:
+        time_until = datetime.datetime.now()
+
+    tags = request.GET.get("tags", None)
+    if tags is not None:
+        tags = request.GET.get("tags").split(" ")
+
+    return [x.as_dict() for x in
+            models.Event.find_events(time_from, time_until, tags=tags)]

+ 20 - 0
docker/blocks/graphite1/files/initial_data.json

@@ -0,0 +1,20 @@
+[
+  {
+    "pk": 1,
+    "model": "auth.user",
+    "fields": {
+      "username": "admin",
+      "first_name": "",
+      "last_name": "",
+      "is_active": true,
+      "is_superuser": true,
+      "is_staff": true,
+      "last_login": "2011-09-20 17:02:14",
+      "groups": [],
+      "user_permissions": [],
+      "password": "sha1$1b11b$edeb0a67a9622f1f2cfeabf9188a711f5ac7d236",
+      "email": "root@example.com",
+      "date_joined": "2011-09-20 17:02:14"
+    }
+  }
+]

+ 42 - 0
docker/blocks/graphite1/files/local_settings.py

@@ -0,0 +1,42 @@
+# Edit this file to override the default graphite settings, do not edit settings.py
+
+# Turn on debugging and restart apache if you ever see an "Internal Server Error" page
+#DEBUG = True
+
+# Set your local timezone (django will try to figure this out automatically)
+TIME_ZONE = 'UTC'
+
+# Setting MEMCACHE_HOSTS to be empty will turn off use of memcached entirely
+#MEMCACHE_HOSTS = ['127.0.0.1:11211']
+
+# Sometimes you need to do a lot of rendering work but cannot share your storage mount
+#REMOTE_RENDERING = True
+#RENDERING_HOSTS = ['fastserver01','fastserver02']
+#LOG_RENDERING_PERFORMANCE = True
+#LOG_CACHE_PERFORMANCE = True
+
+# If you've got more than one backend server they should all be listed here
+#CLUSTER_SERVERS = []
+
+# Override this if you need to provide documentation specific to your graphite deployment
+#DOCUMENTATION_URL = "http://wiki.mycompany.com/graphite"
+
+# Enable email-related features
+#SMTP_SERVER = "mail.mycompany.com"
+
+# LDAP / ActiveDirectory authentication setup
+#USE_LDAP_AUTH = True
+#LDAP_SERVER = "ldap.mycompany.com"
+#LDAP_PORT = 389
+#LDAP_SEARCH_BASE = "OU=users,DC=mycompany,DC=com"
+#LDAP_BASE_USER = "CN=some_readonly_account,DC=mycompany,DC=com"
+#LDAP_BASE_PASS = "readonly_account_password"
+#LDAP_USER_QUERY = "(username=%s)"  #For Active Directory use "(sAMAccountName=%s)"
+
+# If sqlite won't cut it, configure your real database here (don't forget to run manage.py syncdb!)
+#DATABASE_ENGINE = 'mysql' # or 'postgres'
+#DATABASE_NAME = 'graphite'
+#DATABASE_USER = 'graphite'
+#DATABASE_PASSWORD = 'graphite-is-awesome'
+#DATABASE_HOST = 'mysql.mycompany.com'
+#DATABASE_PORT = '3306'

+ 1 - 0
docker/blocks/graphite1/files/my_htpasswd

@@ -0,0 +1 @@
+grafana:$apr1$4R/20xhC$8t37jPP5dbcLr48btdkU//

+ 70 - 0
docker/blocks/graphite1/files/nginx.conf

@@ -0,0 +1,70 @@
+daemon off;
+user www-data;
+worker_processes 1;
+pid /var/run/nginx.pid;
+
+events {
+  worker_connections 1024;
+}
+
+http {
+  sendfile on;
+  tcp_nopush on;
+  tcp_nodelay on;
+  keepalive_timeout 65;
+  types_hash_max_size 2048;
+  server_tokens off;
+
+  server_names_hash_bucket_size 32;
+
+  include /etc/nginx/mime.types;
+  default_type application/octet-stream;
+
+  access_log /var/log/nginx/access.log;
+  error_log /var/log/nginx/error.log;
+
+  gzip on;
+  gzip_disable "msie6";
+
+  server {
+    listen 80 default_server;
+    server_name _;
+
+    open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
+
+    location / {
+        proxy_pass                 http://127.0.0.1:8000;
+        proxy_set_header           X-Real-IP   $remote_addr;
+        proxy_set_header           X-Forwarded-For  $proxy_add_x_forwarded_for;
+        proxy_set_header           X-Forwarded-Proto  $scheme;
+        proxy_set_header           X-Forwarded-Server  $host;
+        proxy_set_header           X-Forwarded-Host  $host;
+        proxy_set_header           Host  $host;
+
+        client_max_body_size       10m;
+        client_body_buffer_size    128k;
+
+        proxy_connect_timeout      90;
+        proxy_send_timeout         90;
+        proxy_read_timeout         90;
+
+        proxy_buffer_size          4k;
+        proxy_buffers              4 32k;
+        proxy_busy_buffers_size    64k;
+        proxy_temp_file_write_size 64k;
+    }
+
+    add_header Access-Control-Allow-Origin "*";
+    add_header Access-Control-Allow-Methods "GET, OPTIONS";
+    add_header Access-Control-Allow-Headers "origin, authorization, accept";
+
+    location /content {
+      alias /opt/graphite/webapp/content;
+
+    }
+
+    location /media {
+      alias /usr/share/pyshared/django/contrib/admin/media;
+    }
+  }
+}

+ 8 - 0
docker/blocks/graphite1/files/statsd_config.js

@@ -0,0 +1,8 @@
+{
+  graphitePort: 2003,
+  graphiteHost: "127.0.0.1",
+  port: 8125,
+  mgmt_port: 8126,
+  backends: ['./backends/graphite'],
+  debug: true
+}

+ 19 - 0
docker/blocks/graphite1/files/storage-aggregation.conf

@@ -0,0 +1,19 @@
+[min]
+pattern = \.min$
+xFilesFactor = 0.1
+aggregationMethod = min
+
+[max]
+pattern = \.max$
+xFilesFactor = 0.1
+aggregationMethod = max
+
+[sum]
+pattern = \.count$
+xFilesFactor = 0
+aggregationMethod = sum
+
+[default_average]
+pattern = .*
+xFilesFactor = 0.5
+aggregationMethod = average

+ 16 - 0
docker/blocks/graphite1/files/storage-schemas.conf

@@ -0,0 +1,16 @@
+[carbon]
+pattern = ^carbon\..*
+retentions = 1m:31d,10m:1y,1h:5y
+
+[highres]
+pattern = ^highres.*
+retentions = 1s:1d,1m:7d
+
+[statsd]
+pattern = ^statsd.*
+retentions = 1m:7d,10m:1y
+
+[default]
+pattern = .*
+retentions = 10s:1d,1m:7d,10m:1y
+

+ 26 - 0
docker/blocks/graphite1/files/supervisord.conf

@@ -0,0 +1,26 @@
+[supervisord]
+nodaemon = true
+environment = GRAPHITE_STORAGE_DIR='/opt/graphite/storage',GRAPHITE_CONF_DIR='/opt/graphite/conf'
+
+[program:nginx]
+command = /usr/sbin/nginx
+stdout_logfile = /var/log/supervisor/%(program_name)s.log
+stderr_logfile = /var/log/supervisor/%(program_name)s.log
+autorestart = true
+
+[program:carbon-cache]
+;user = www-data
+command = /opt/graphite/bin/carbon-cache.py --debug start
+stdout_logfile = /var/log/supervisor/%(program_name)s.log
+stderr_logfile = /var/log/supervisor/%(program_name)s.log
+autorestart = true
+
+[program:graphite-webapp]
+;user = www-data
+directory = /opt/graphite/webapp
+environment = PYTHONPATH='/opt/graphite/webapp'
+command = /usr/bin/gunicorn_django -b127.0.0.1:8000 -w2 graphite/settings.py
+stdout_logfile = /var/log/supervisor/%(program_name)s.log
+stderr_logfile = /var/log/supervisor/%(program_name)s.log
+autorestart = true
+

+ 17 - 0
docker/blocks/influxdb/docker-compose.yaml

@@ -0,0 +1,17 @@
+  influxdb:
+    image: influxdb:latest
+    container_name: influxdb
+    ports:
+      - "2004:2004"
+      - "8083:8083"
+      - "8086:8086"
+    volumes:
+      - ./blocks/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf
+
+  fake-influxdb-data:
+    image: grafana/fake-data-gen
+    network_mode: bridge
+    environment:
+      FD_DATASOURCE: influxdb
+      FD_PORT: 8086
+

+ 0 - 17
docker/blocks/influxdb/fig

@@ -1,17 +0,0 @@
-influxdb:
-  image: influxdb:latest
-  container_name: influxdb
-  ports:
-    - "2004:2004"
-    - "8083:8083"
-    - "8086:8086"
-  volumes:
-    - ./blocks/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf
-
-fake-influxdb-data:
-  image: grafana/fake-data-gen
-  net: bridge
-  environment:
-    FD_DATASOURCE: influxdb
-    FD_PORT: 8086
-

+ 6 - 0
docker/blocks/jaeger/docker-compose.yaml

@@ -0,0 +1,6 @@
+  jaeger:
+    image: jaegertracing/all-in-one:latest
+    ports:
+      - "127.0.0.1:6831:6831/udp"
+      - "16686:16686"
+

+ 5 - 0
docker/blocks/memcached/docker-compose.yaml

@@ -0,0 +1,5 @@
+  memcached:
+    image: memcached:latest
+    ports:
+      - "11211:11211"
+

+ 0 - 5
docker/blocks/memcached/fig

@@ -1,5 +0,0 @@
-memcached:
-  image: memcached:latest
-  ports:
-    - "11211:11211"
-

+ 14 - 0
docker/blocks/mysql/docker-compose.yaml

@@ -0,0 +1,14 @@
+  mysql:
+    image: mysql:latest
+    environment:
+      MYSQL_ROOT_PASSWORD: rootpass
+      MYSQL_DATABASE: grafana
+      MYSQL_USER: grafana
+      MYSQL_PASSWORD: password
+    ports:
+      - "3306:3306"
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - /etc/timezone:/etc/timezone:ro
+    command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --innodb_monitor_enable=all]
+

+ 0 - 9
docker/blocks/mysql/fig

@@ -1,9 +0,0 @@
-mysql:
-  image: mysql:latest
-  environment:
-    MYSQL_ROOT_PASSWORD: rootpass
-    MYSQL_DATABASE: grafana
-    MYSQL_USER: grafana
-    MYSQL_PASSWORD: password
-  ports:
-    - "3306:3306"

+ 20 - 0
docker/blocks/mysql_opendata/Dockerfile

@@ -0,0 +1,20 @@
+## MySQL with Open Data Set from NYC Open Data (https://data.cityofnewyork.us)
+
+FROM mysql:latest
+
+ENV MYSQL_DATABASE="testdata" \
+    MYSQL_ROOT_PASSWORD="rootpass" \
+    MYSQL_USER="grafana" \
+    MYSQL_PASSWORD="password"
+
+# Install requirement (wget)
+RUN apt-get update && apt-get install -y wget && apt-get install unzip
+
+# Fetch NYC Data Set
+RUN wget https://data.cityofnewyork.us/download/57g5-etyj/application%2Fzip -O /tmp/data.zip && \
+  unzip -j /tmp/data.zip 311_Service_Requests_from_2015.csv -d /var/lib/mysql-files && \
+  rm /tmp/data.zip
+
+ADD import_csv.sql /docker-entrypoint-initdb.d/
+
+EXPOSE 3306

+ 9 - 0
docker/blocks/mysql_opendata/docker-compose.yaml

@@ -0,0 +1,9 @@
+  mysql_opendata:
+    build: blocks/mysql_opendata
+    environment:
+      MYSQL_ROOT_PASSWORD: rootpass
+      MYSQL_DATABASE: testdata
+      MYSQL_USER: grafana
+      MYSQL_PASSWORD: password
+    ports:
+      - "3307:3306"

+ 80 - 0
docker/blocks/mysql_opendata/import_csv.sql

@@ -0,0 +1,80 @@
+use testdata;
+DROP TABLE IF EXISTS `nyc_open_data`;
+CREATE TABLE IF NOT EXISTS `nyc_open_data` (
+  UniqueKey bigint(255),
+  `CreatedDate` varchar(255),
+  `ClosedDate` varchar(255),
+  Agency varchar(255),
+  AgencyName varchar(255),
+  ComplaintType varchar(255),
+  Descriptor varchar(255),
+  LocationType varchar(255),
+  IncidentZip varchar(255),
+  IncidentAddress varchar(255),
+  StreetName varchar(255),
+  CrossStreet1 varchar(255),
+  CrossStreet2 varchar(255),
+  IntersectionStreet1 varchar(255),
+  IntersectionStreet2 varchar(255),
+  AddressType varchar(255),
+  City varchar(255),
+  Landmark varchar(255),
+  FacilityType varchar(255),
+  Status varchar(255),
+  `DueDate` varchar(255),
+  ResolutionDescription varchar(2048),
+  `ResolutionActionUpdatedDate` varchar(255),
+  CommunityBoard varchar(255),
+  Borough varchar(255),
+  XCoordinateStatePlane varchar(255),
+  YCoordinateStatePlane varchar(255),
+  ParkFacilityName varchar(255),
+  ParkBorough varchar(255),
+  SchoolName varchar(255),
+  SchoolNumber varchar(255),
+  SchoolRegion varchar(255),
+  SchoolCode varchar(255),
+  SchoolPhoneNumber varchar(255),
+  SchoolAddress varchar(255),
+  SchoolCity varchar(255),
+  SchoolState varchar(255),
+  SchoolZip varchar(255),
+  SchoolNotFound varchar(255),
+  SchoolOrCitywideComplaint varchar(255),
+  VehicleType varchar(255),
+  TaxiCompanyBorough varchar(255),
+  TaxiPickUpLocation varchar(255),
+  BridgeHighwayName varchar(255),
+  BridgeHighwayDirection varchar(255),
+  RoadRamp varchar(255),
+  BridgeHighwaySegment varchar(255),
+  GarageLotName varchar(255),
+  FerryDirection varchar(255),
+  FerryTerminalName varchar(255),
+  Latitude varchar(255),
+  Longitude varchar(255),
+  Location varchar(255)
+);
+LOAD DATA INFILE '/var/lib/mysql-files/311_Service_Requests_from_2015.csv' INTO TABLE nyc_open_data FIELDS OPTIONALLY ENCLOSED BY '"' TERMINATED BY ',' IGNORE 1 LINES;
+UPDATE nyc_open_data SET CreatedDate = STR_TO_DATE(CreatedDate, '%m/%d/%Y %r') WHERE CreatedDate <> '';
+UPDATE nyc_open_data SET ClosedDate = STR_TO_DATE(ClosedDate, '%m/%d/%Y %r') WHERE ClosedDate <> '';
+UPDATE nyc_open_data SET DueDate = STR_TO_DATE(DueDate, '%m/%d/%Y %r') WHERE DueDate <> '';
+UPDATE nyc_open_data SET ResolutionActionUpdatedDate = STR_TO_DATE(ResolutionActionUpdatedDate, '%m/%d/%Y %r') WHERE ResolutionActionUpdatedDate <> '';
+
+UPDATE nyc_open_data SET CreatedDate=null WHERE CreatedDate = '';
+UPDATE nyc_open_data SET ClosedDate=null WHERE ClosedDate = '';
+UPDATE nyc_open_data SET DueDate=null WHERE DueDate = '';
+UPDATE nyc_open_data SET ResolutionActionUpdatedDate=null WHERE ResolutionActionUpdatedDate = '';
+
+ALTER TABLE nyc_open_data modify CreatedDate datetime NULL;
+ALTER TABLE nyc_open_data modify ClosedDate datetime NULL;
+ALTER TABLE nyc_open_data modify DueDate datetime NULL;
+ALTER TABLE nyc_open_data modify ResolutionActionUpdatedDate datetime NULL;
+
+ALTER TABLE `nyc_open_data` ADD INDEX `IX_ComplaintType` (`ComplaintType`);
+ALTER TABLE `nyc_open_data` ADD INDEX `IX_CreatedDate` (`CreatedDate`);
+ALTER TABLE `nyc_open_data` ADD INDEX `IX_LocationType` (`LocationType`);
+ALTER TABLE `nyc_open_data` ADD INDEX `IX_AgencyName` (`AgencyName`);
+ALTER TABLE `nyc_open_data` ADD INDEX `IX_City` (`City`);
+
+SYSTEM rm /var/lib/mysql-files/311_Service_Requests_from_2015.csv

+ 9 - 0
docker/blocks/mysql_tests/docker-compose.yaml

@@ -0,0 +1,9 @@
+  mysqltests:
+    image: mysql:latest
+    environment:
+      MYSQL_ROOT_PASSWORD: rootpass
+      MYSQL_DATABASE: grafana_tests
+      MYSQL_USER: grafana
+      MYSQL_PASSWORD: password
+    ports:
+      - "3306:3306"

+ 0 - 9
docker/blocks/mysql_tests/fig

@@ -1,9 +0,0 @@
-mysqltests:
-  image: mysql:latest
-  environment:
-    MYSQL_ROOT_PASSWORD: rootpass
-    MYSQL_DATABASE: grafana_tests
-    MYSQL_USER: grafana
-    MYSQL_PASSWORD: password
-  ports:
-    - "3306:3306"

+ 10 - 0
docker/blocks/openldap/docker-compose.yaml

@@ -0,0 +1,10 @@
+  openldap:
+    build: blocks/openldap
+    environment:
+      SLAPD_PASSWORD: grafana
+      SLAPD_DOMAIN: grafana.org
+      SLAPD_ADDITIONAL_MODULES: memberof
+    ports:
+      - "389:389"
+
+

+ 0 - 10
docker/blocks/openldap/fig

@@ -1,10 +0,0 @@
-openldap:
-  build: blocks/openldap
-  environment:
-    SLAPD_PASSWORD: grafana
-    SLAPD_DOMAIN: grafana.org
-    SLAPD_ADDITIONAL_MODULES: memberof
-  ports:
-    - "389:389"
-
-

+ 11 - 0
docker/blocks/opentsdb/docker-compose.yaml

@@ -0,0 +1,11 @@
+  opentsdb:
+    image: opower/opentsdb:latest
+    ports:
+      - "4242:4242"
+
+  fake-opentsdb-data:
+    image: grafana/fake-data-gen
+    network_mode: bridge
+    environment:
+      FD_DATASOURCE: opentsdb
+

+ 0 - 11
docker/blocks/opentsdb/fig

@@ -1,11 +0,0 @@
-opentsdb:
-  image: opower/opentsdb:latest
-  ports:
-    - "4242:4242"
-
-fake-opentsdb-data:
-  image: grafana/fake-data-gen
-  net: bridge
-  environment:
-    FD_DATASOURCE: opentsdb
-

+ 9 - 0
docker/blocks/postgres/docker-compose.yaml

@@ -0,0 +1,9 @@
+  postgrestest:
+    image: postgres:latest
+    environment:
+      POSTGRES_USER: grafana
+      POSTGRES_PASSWORD: password
+      POSTGRES_DATABASE: grafana
+    ports:
+      - "5432:5432"
+    command: postgres -c log_connections=on -c logging_collector=on -c log_destination=stderr -c log_directory=/var/log/postgresql

+ 0 - 8
docker/blocks/postgres/fig

@@ -1,8 +0,0 @@
-postgrestest:
-  image: postgres:latest
-  environment:
-    POSTGRES_USER: grafana
-    POSTGRES_PASSWORD: password
-    POSTGRES_DATABASE: grafana
-  ports:
-    - "5432:5432"

+ 7 - 0
docker/blocks/postgres_tests/docker-compose.yaml

@@ -0,0 +1,7 @@
+  postgrestest:
+    image: postgres:latest
+    environment:
+      POSTGRES_USER: grafanatest
+      POSTGRES_PASSWORD: grafanatest
+    ports:
+      - "5432:5432"

+ 0 - 7
docker/blocks/postgres_tests/fig

@@ -1,7 +0,0 @@
-postgrestest:
-  image: postgres:latest
-  environment:
-    POSTGRES_USER: grafanatest
-    POSTGRES_PASSWORD: grafanatest
-  ports:
-    - "5432:5432"

+ 1 - 0
docker/blocks/prometheus/Dockerfile

@@ -1,2 +1,3 @@
 FROM prom/prometheus
 ADD prometheus.yml /etc/prometheus/
+ADD alert.rules /etc/prometheus/

+ 10 - 0
docker/blocks/prometheus/alert.rules

@@ -0,0 +1,10 @@
+# Alert Rules
+
+ALERT AppCrash
+  IF process_open_fds > 0
+  FOR 15s
+  LABELS { severity="critical" }
+  ANNOTATIONS {
+   summary = "Number of open fds > 0",
+   description = "Just testing"
+  }

+ 25 - 0
docker/blocks/prometheus/docker-compose.yaml

@@ -0,0 +1,25 @@
+  prometheus:
+    build: blocks/prometheus
+    network_mode: host
+    ports:
+      - "9090:9090"
+
+  node_exporter:
+    image: prom/node-exporter
+    network_mode: host
+    ports:
+      - "9100:9100"
+
+  fake-prometheus-data:
+    image: grafana/fake-data-gen
+    network_mode: host
+    ports:
+      - "9091:9091"
+    environment:
+      FD_DATASOURCE: prom
+
+  alertmanager:
+    image: quay.io/prometheus/alertmanager
+    network_mode: host
+    ports:
+      - "9093:9093"

+ 0 - 22
docker/blocks/prometheus/fig

@@ -1,22 +0,0 @@
-prometheus:
-  build: blocks/prometheus
-  net: host
-  ports:
-    - "9090:9090"
-  volumes:
-    - /var/docker/prometheus:/prometheus-data
-
-node_exporter:
-  image: prom/node-exporter
-  net: host
-  ports:
-    - "9100:9100"
-
-fake-prometheus-data:
-  image: grafana/fake-data-gen
-  net: host
-  ports:
-    - "9091:9091"
-  environment:
-    FD_DATASOURCE: prom
-

+ 20 - 12
docker/blocks/prometheus/prometheus.yml

@@ -6,22 +6,30 @@ global:
 
 # Load and evaluate rules in this file every 'evaluation_interval' seconds.
 rule_files:
+  - "alert.rules"
   # - "first.rules"
   # - "second.rules"
 
-# A scrape configuration containing exactly one endpoint to scrape:
-# Here it's Prometheus itself.
+alerting:
+  alertmanagers:
+  - scheme: http
+    static_configs:
+    - targets:
+      - "127.0.0.1:9093"
+
 scrape_configs:
-  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
   - job_name: 'prometheus'
+    static_configs:
+      - targets: ['localhost:9090']
 
-    # Override the global default and scrape targets from this job every 5 seconds.
-    scrape_interval: 10s
-    scrape_timeout: 10s
-
-    # metrics_path defaults to '/metrics'
-    # scheme defaults to 'http'.
-
+  - job_name: 'node_exporter'
+    static_configs:
+      - targets: ['127.0.0.1:9100']
+ 
+  - job_name: 'fake-data-gen'
+    static_configs:
+      - targets: ['127.0.0.1:9091']
+  
+  - job_name: 'grafana'
     static_configs:
-      #- targets: ['localhost:9090', '172.17.0.1:9091', '172.17.0.1:9100', '172.17.0.1:9150']
-      - targets: ['localhost:9090', '127.0.0.1:9091', '127.0.0.1:9100', '127.0.0.1:9150']
+      - targets: ['127.0.0.1:3000']

Некоторые файлы не были показаны из-за большого количества измененных файлов