├── DatadogMonitoring.rsc ├── LICENSE ├── LoadGlobalFunctions.rsc ├── README.md ├── datadog-dashboard-examples └── dual-wan-example.json └── datadog-public-dashboard-example.png /DatadogMonitoring.rsc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | # Datadog API Settings 4 | :local apikey "a1b2c3...DATADOG APIKEY"; 5 | :local applicationkey "a1b2c3...DATADOG APPLICATION KEY"; 6 | :local ddendpoint "https://app.datadoghq.com/api/v1"; 7 | :local type "gauge"; 8 | :local tags "source:mikrotik"; 9 | 10 | # Misc variables for stuff and things. 11 | :local metrics; 12 | :local metric ""; 13 | :local value ""; 14 | :local httpdata ""; 15 | :local datetime [$timestamp]; 16 | :local identity [/system identity get name]; 17 | 18 | # Exceptional metrics pre-declared due to some additional checks 19 | 20 | # system resource bad-blocks 21 | :local badblocks [/system resource get bad-blocks]; 22 | :if ([:len $badblocks] = 0) do={ 23 | :set badblocks 0; 24 | } 25 | 26 | # system resource write-sect-total 27 | :local writesecttotal [/system resource get write-sect-total]; 28 | :if ([:len $writesecttotal] = 0) do={ 29 | :set writesecttotal 0; 30 | } 31 | 32 | # system resource write-sect-since-reboot 33 | :local writesectsincereboot [/system resource get write-sect-since-reboot]; 34 | :if ([:len $writesectsincereboot] = 0) do={ 35 | :set writesectsincereboot 0; 36 | } 37 | 38 | # system health voltage 39 | :local healthvoltage [/system health get voltage]; 40 | :if ([:len $healthvoltage] = 0) do={ 41 | :set healthvoltage 0; 42 | } 43 | 44 | # system health current 45 | :local healthcurrent [/system health get current]; 46 | :if ([:len $healthcurrent] = 0) do={ 47 | :set healthcurrent 0; 48 | } 49 | 50 | # system health temperature 51 | :local healthtemperature [/system health get temperature]; 52 | :if ([:len $healthtemperature] = 0) do={ 53 | :set healthtemperature 0; 54 | } 55 | 56 | # system health cpu-temperature 57 | :local healthcputemperature [/system health get cpu-temperature]; 58 | :if ([:len $healthcputemperature] = 0) do={ 59 | :set healthcputemperature 0; 60 | } 61 | 62 | # system health power-consumption 63 | :local healthpowerconsumption [/system health get power-consumption]; 64 | :if ([:len $healthpowerconsumption] = 0) do={ 65 | :set healthpowerconsumption 0; 66 | } 67 | 68 | # system health fan1-speed 69 | :local healthfan1speed [/system health get fan1-speed]; 70 | :if ([:len $healthfan1speed] = 0) do={ 71 | :set healthfan1speed 0; 72 | } 73 | 74 | # system health fan2-speed 75 | :local healthfan2speed [/system health get fan2-speed]; 76 | :if ([:len $healthfan2speed] = 0) do={ 77 | :set healthfan2speed 0; 78 | } 79 | 80 | # Create metrics array 81 | :set metrics { 82 | "system.cpu.load"=[/system resource get cpu-load]; 83 | "system.memory.total"=[/system resource get total-memory]; 84 | "system.memory.free"=[/system resource get free-memory]; 85 | "system.disk.hddspace.total"=[/system resource get total-hdd-space]; 86 | "system.disk.hddspace.free"=[/system resource get free-hdd-space]; 87 | "system.disk.writesect.total"=$writesecttotal; 88 | "system.disk.writesect.sincereboot"=$writesectsincereboot; 89 | "system.disk.badblocks"=$badblocks; 90 | "system.firewall.connections"=[/ip firewall connection print count-only]; 91 | "system.ppp.all"=[/ppp active print count-only]; 92 | "system.ppp.sstp"=[/ppp active print count-only where service=sstp]; 93 | "system.ppp.pptp"=[/ppp active print count-only where service=pptp]; 94 | "system.ppp.ovpn"=[/ppp active print count-only where service=ovpn]; 95 | "system.ppp.pppoe"=[/ppp active print count-only where service=pppoe]; 96 | "system.ppp.l2tp"=[/ppp active print count-only where service=l2tp]; 97 | "system.health.voltage"=$healthvoltage; 98 | "system.health.current"=$healthcurrent; 99 | "system.health.temperature"=$healthtemperature; 100 | "system.health.temperature.cpu"=$healthcputemperature; 101 | "system.health.consumption"=$healthpowerconsumption; 102 | "system.health.fanspeed.1"=$healthfan1speed; 103 | "system.health.fanspeed.2"=$healthfan2speed; 104 | } 105 | 106 | # Additional values that we can add to main metrics array 107 | 108 | # monitor-traffic tx/rx bps on all ethernet interfaces 109 | :foreach interface in=[/interface ethernet find] do={ 110 | :local intfName [/interface get $interface name]; 111 | /interface monitor-traffic $intfName once do={ 112 | :set ($metrics->("system.interfaces.".$intfName.".tx-bits-per-second")) (tx-bits-per-second / 1024); 113 | :set ($metrics->("system.interfaces.".$intfName.".rx-bits-per-second")) (rx-bits-per-second / 1024); 114 | } 115 | } 116 | 117 | # monitor-traffic tx/rx bps on all vlan interfaces 118 | :foreach interface in=[/interface vlan find] do={ 119 | :local intfName [/interface get $interface name]; 120 | /interface monitor-traffic $intfName once do={ 121 | :set ($metrics->("system.interfaces.".$intfName.".tx-bits-per-second")) (tx-bits-per-second / 1024); 122 | :set ($metrics->("system.interfaces.".$intfName.".rx-bits-per-second")) (rx-bits-per-second / 1024); 123 | } 124 | } 125 | 126 | # monitor-traffic tx/rx bps on all bridge interfaces 127 | :foreach interface in=[/interface bridge find] do={ 128 | :local intfName [/interface get $interface name]; 129 | /interface monitor-traffic $intfName once do={ 130 | :set ($metrics->("system.interfaces.".$intfName.".tx-bits-per-second")) (tx-bits-per-second / 1024); 131 | :set ($metrics->("system.interfaces.".$intfName.".rx-bits-per-second")) (rx-bits-per-second / 1024); 132 | } 133 | } 134 | 135 | # monitor-traffic tx/rx bps on all bonding interfaces 136 | :foreach interface in=[/interface bonding find] do={ 137 | :local intfName [/interface get $interface name]; 138 | /interface monitor-traffic $intfName once do={ 139 | :set ($metrics->("system.interfaces.".$intfName.".tx-bits-per-second")) (tx-bits-per-second / 1024); 140 | :set ($metrics->("system.interfaces.".$intfName.".rx-bits-per-second")) (rx-bits-per-second / 1024); 141 | } 142 | } 143 | 144 | # monitor-traffic tx/rx bps on all pppoe-client interfaces 145 | :foreach interface in=[/interface pppoe-client find] do={ 146 | :local intfName [/interface get $interface name]; 147 | /interface monitor-traffic $intfName once do={ 148 | :set ($metrics->("system.interfaces.".$intfName.".tx-bits-per-second")) (tx-bits-per-second / 1024); 149 | :set ($metrics->("system.interfaces.".$intfName.".rx-bits-per-second")) (rx-bits-per-second / 1024); 150 | } 151 | } 152 | 153 | # Datadog JSON data to parse with Datadog API post-timeseries-points 154 | 155 | # Open Series 156 | :set httpdata ($httpdata."{\"series\":["); 157 | 158 | :foreach metric,value in=($metrics) do={ 159 | :set httpdata ($httpdata."{\"metric\":\"".$metric."\",\"points\":[[".$datetime.",".$value."]],\"type\":\"".$type."\",\"tags\":\"".$tags."\",\"host\":\"".$identity."\"},"); 160 | } 161 | 162 | # Remove "," on latest "}" when append last info or you will get a 400 Bad Request 163 | # Payload is not in the expected format: invalid character ']' looking for beginning of value 164 | 165 | # set system.uptime metric as closing series 166 | :set $metric "system.uptime"; 167 | :set $value [$uptimeseconds]; 168 | :set httpdata ($httpdata."{\"metric\":\"".$metric."\",\"points\":[[".$datetime.",".$value."]],\"type\":\"".$type."\",\"tags\":\"".$tags."\",\"host\":\"".$identity."\"}"); 169 | 170 | # Close Series 171 | :set httpdata ($httpdata."]}"); 172 | 173 | # Call API via POST 174 | :set ddendpoint ($ddendpoint."/series\?api_key=".$apikey."&application_key=".$applicationkey); 175 | /tool fetch keep-result=no mode=https http-method=post http-header-field="Content-Type:application/json" http-data=$httpdata url=$ddendpoint; 176 | 177 | } 178 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Manuele Trimarchi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LoadGlobalFunctions.rsc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | # Julian Calendar function 4 | :global functionJulianDate do={ 5 | 6 | :local months [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"]; 7 | :local jd 8 | :local M [:pick $1 0 3]; 9 | :local D [:pick $1 4 6]; 10 | :local Y [:pick $1 7 11]; 11 | 12 | :for x from=0 to=([:len $months] - 1) do={ 13 | :if ([:tostr [:pick $months $x]] = $M) do={:set M ($x + 1) } 14 | } 15 | :if ( $M = 1 || $M = 2) do={ 16 | :set Y ($Y-1); 17 | :set M ($M+12); 18 | } 19 | 20 | :local A ($Y/100) 21 | :local B ($A/4) 22 | :local C (2-$A+$B) 23 | :local E ((($Y+4716) * 36525)/100) 24 | :local F ((306001*($M+1))/10000) 25 | return ($C+$D+$E+$F-1525) 26 | }; 27 | 28 | # Timestamp function to get UNIX POSIX timestamp in UTC timezone 29 | :global timestamp do={ 30 | 31 | :global functionJulianDate $functionJulianDate 32 | :local currenttime [/system clock get time]; 33 | :local jdnow [$functionJulianDate [/system clock get date]] 34 | :local days ($jdnow - 2440587) 35 | :local hours [:pick $currenttime 0 2] 36 | :local minutes [:pick $currenttime 3 5] 37 | :local seconds [:pick $currenttime 6 8] 38 | 39 | return (($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds - [/system clock get gmt-offset]); 40 | } 41 | 42 | # Get uptime in seconds 43 | :global uptimeseconds do={ 44 | 45 | :local UptimeSeconds 0; 46 | :local uptime [/system resource get uptime]; 47 | :local weekend 0; 48 | :local dayend 0; 49 | :local weeks 0; 50 | :local days 0; 51 | 52 | :if ([:find $uptime "w" -1] > 0) do={ 53 | :set weekend [:find $uptime "w" -1]; 54 | :set weeks [:pick $uptime 0 $weekend]; 55 | :set weekend ($weekend+1); 56 | }; 57 | 58 | :if ([:find $uptime "d" -1] > 0) do={ 59 | :set dayend [:find $uptime "d" -1]; 60 | :set days [:pick $uptime $weekend $dayend]; 61 | }; 62 | 63 | :local time [:pick $uptime ([:len $uptime]-8) [:len $uptime]]; 64 | 65 | :local hours [:pick $time 0 2]; 66 | :local minutes [:pick $time 3 5]; 67 | :local seconds [:pick $time 6 8]; 68 | 69 | return ($weeks*86400*7+$days*86400+$hours*3600+$minutes*60+$seconds); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MikrotikJSON4DatadogAPI 2 | 3 | This is a simple example to generate and push metrics in JSON format to Datadog API using RouterOS scripting language. 4 | 5 | I'm using [Timeseries Points](https://docs.datadoghq.com/api/?lang=bash#post-timeseries-points) `POST` Datadog API call. 6 | 7 | 8 | With this example you can generate a dashboard like that: 9 | 10 | ![datadog-public-dashboard-example](https://github.com/mtrimarchi/MikrotikJSON4DatadogAPI/raw/master/datadog-public-dashboard-example.png "Datadog public dashboard example") 11 | 12 | So, let's go! 13 | 14 | # First step, LoadGlobalFunctions.rsc 15 | 16 | At first, we need to add some basic global functions and load them on startup. 17 | 18 | You have to go on `System \ Scheduler` and add a new Schedule. 19 | 20 | Configure the schedule this way: 21 | - **Schedule name** → `LoadAllFunctions` 22 | - **Start Date** → `Nov/27/2018` 23 | - **Start Time** → `startup` 24 | - **Interval** → `00:00:00` 25 | - **On Event** → _just copy/paste [LoadGlobalFunctions.rsc](https://github.com/mtrimarchi/MikrotikJSON4DatadogAPI/raw/master/LoadGlobalFunctions.rsc) content_ 26 | 27 | Ok, now if we reboot our router we will get loaded three functions. We can find them on `System \ Scripts \ Environment`. 28 | 29 | These loaded scripts are named: 30 | - **functionJulianDate** _Julian Calendar function wich convert RouterOS date call in JD format seconds_ 31 | - **timestamp** _Timestamp function to get UNIX POSIX timestamp in UTC timezone_ 32 | - **uptimeseconds** _Get uptime in seconds_ 33 | 34 | # Second step, DatadogMonitoring.rsc 35 | 36 | First of all we need to generate an `API Key` and a new `Application Key`. We can do it [here](https://app.datadoghq.com/account/settings#api). 37 | 38 | Once created both keys, as already done before, we have to add a new Schedule. This one generate the JSON data and push it to Datadog API using `fetch` command. We need to adapt vars on the script because when we call Datadog API we need to identify ourself with the generated `API key` and `Application key`. 39 | 40 | When you copy [DatadogMonitoring.rsc](https://github.com/mtrimarchi/MikrotikJSON4DatadogAPI/raw/master/DatadogMonitoring.rsc) pay attention to the first part of the script identified as "Datadog API Settings". 41 | 42 | Adapt all the values: 43 | - **apikey** → _Your API keys are unique to your organization. An API key is required by the Datadog Agent to submit metrics and events to Datadog._ 44 | - **applicationkey** → _Application keys, in conjunction with your org's API key, give you full access to Datadog's programmatic API. Application keys are associated with the user account that created them and can be named. The application key is used to log all requests made to the API._ 45 | - **ddendpoint** → `"https://app.datadoghq.com/api/v1"` _URL Datadog API endpoint._ 46 | - **type** → `"gauge"` _[optional, default=gauge]: Type of your metric either: gauge, rate, or count._ 47 | - **tags** → `"source:mikrotik"` _[optional, default=None]: A list of tags associated with the metric._ 48 | 49 | Now you have to go once again on `System \ Scheduler` and add a new Schedule. 50 | 51 | Configure the schedule this way: 52 | - **Schedule name** → `DatadogMonitoring` 53 | - **Start Date** → `Nov/27/2018` 54 | - **Start Time** → `00:00:00` 55 | - **Interval** → `00:00:05` 56 | - **On Event** → _copy/paste the modified content of DatadogMonitoring.rsc_ 57 | 58 | You can adjust `Interval` seconds value in order to change the frequency timeframe for generation and push of the JSON to Datadog. 59 | 60 | # Let's test! 61 | 62 | You can see `system.cpu.load` metric using `Metrics Explorer` on Datadog website. 63 | 64 | Click here for an example: [https://app.datadoghq.com/metric/explorer?live=true&exp_metric=system.cpu.load](https://app.datadoghq.com/metric/explorer?live=true&exp_metric=system.cpu.load) 65 | -------------------------------------------------------------------------------- /datadog-dashboard-examples/dual-wan-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "title":"Mikrotik Router with Dual WAN", 3 | "description":"Dashboard for a router with ether1 and ether2 used as uplink WAN connectivity", 4 | "widgets":[ 5 | { 6 | "id":123456789001, 7 | "definition":{ 8 | "type":"timeseries", 9 | "requests":[ 10 | { 11 | "q":"avg:system.cpu.load{$host}", 12 | "display_type":"line", 13 | "style":{ 14 | "palette":"dog_classic", 15 | "line_type":"solid", 16 | "line_width":"normal" 17 | } 18 | } 19 | ], 20 | "custom_links":[ 21 | 22 | ], 23 | "yaxis":{ 24 | "min":"0", 25 | "max":"100" 26 | }, 27 | "markers":[ 28 | { 29 | "value":"y = 30", 30 | "display_type":"warning dashed" 31 | }, 32 | { 33 | "value":"40 < y < 100", 34 | "display_type":"error dashed", 35 | "label":"Error threshold" 36 | } 37 | ], 38 | "title":"System CPU Load", 39 | "title_size":"13", 40 | "title_align":"center", 41 | "show_legend":true, 42 | "legend_size":"0" 43 | }, 44 | "layout":{ 45 | "x":1, 46 | "y":20, 47 | "width":47, 48 | "height":15 49 | } 50 | }, 51 | { 52 | "id":123456789002, 53 | "definition":{ 54 | "type":"timeseries", 55 | "requests":[ 56 | { 57 | "q":"sum:system.memory.free{$host}, sum:system.memory.total{$host}-sum:system.memory.free{$host}", 58 | "metadata":[ 59 | { 60 | "expression":"sum:system.memory.free{$host}", 61 | "alias_name":"Free Memory" 62 | }, 63 | { 64 | "expression":"sum:system.memory.total{$host}-sum:system.memory.free{$host}", 65 | "alias_name":"Used Memory" 66 | } 67 | ], 68 | "display_type":"area", 69 | "style":{ 70 | "palette":"orange", 71 | "line_type":"solid", 72 | "line_width":"normal" 73 | } 74 | } 75 | ], 76 | "custom_links":[ 77 | 78 | ], 79 | "yaxis":{ 80 | "min":"0" 81 | }, 82 | "title":"System RAM", 83 | "title_size":"13", 84 | "title_align":"center", 85 | "show_legend":true, 86 | "legend_size":"0" 87 | }, 88 | "layout":{ 89 | "x":49, 90 | "y":20, 91 | "width":47, 92 | "height":15 93 | } 94 | }, 95 | { 96 | "id":123456789003, 97 | "definition":{ 98 | "type":"timeseries", 99 | "requests":[ 100 | { 101 | "q":"avg:system.firewall.connections{$host}", 102 | "display_type":"bars", 103 | "style":{ 104 | "palette":"orange", 105 | "line_type":"solid", 106 | "line_width":"normal" 107 | } 108 | } 109 | ], 110 | "custom_links":[ 111 | 112 | ], 113 | "title":"Connection Tracking Active Sessions", 114 | "title_size":"13", 115 | "title_align":"center", 116 | "show_legend":true, 117 | "legend_size":"0" 118 | }, 119 | "layout":{ 120 | "x":1, 121 | "y":36, 122 | "width":47, 123 | "height":15 124 | } 125 | }, 126 | { 127 | "id":12345678900, 128 | "definition":{ 129 | "type":"timeseries", 130 | "requests":[ 131 | { 132 | "q":"(avg:system.interfaces.ether1.rx_bits_per_second{$host}+avg:system.interfaces.ether2.rx_bits_per_second{$host})*1000", 133 | "metadata":[ 134 | { 135 | "expression":"(avg:system.interfaces.ether1.rx_bits_per_second{$host}+avg:system.interfaces.ether2.rx_bits_per_second{$host})*1000", 136 | "alias_name":"WAN Download" 137 | } 138 | ], 139 | "display_type":"area", 140 | "style":{ 141 | "palette":"orange", 142 | "line_type":"solid", 143 | "line_width":"normal" 144 | } 145 | }, 146 | { 147 | "q":"(avg:system.interfaces.ether1.tx_bits_per_second{$host}+avg:system.interfaces.ether2.tx_bits_per_second{$host})*1000", 148 | "metadata":[ 149 | { 150 | "expression":"(avg:system.interfaces.ether1.tx_bits_per_second{$host}+avg:system.interfaces.ether2.tx_bits_per_second{$host})*1000", 151 | "alias_name":"WAN Upload" 152 | } 153 | ], 154 | "display_type":"area", 155 | "style":{ 156 | "palette":"purple", 157 | "line_type":"solid", 158 | "line_width":"normal" 159 | } 160 | } 161 | ], 162 | "yaxis":{ 163 | "label":"", 164 | "scale":"linear", 165 | "min":"auto", 166 | "max":"auto", 167 | "include_zero":true 168 | }, 169 | "title":"WAN I/O Rate", 170 | "title_size":"13", 171 | "title_align":"center", 172 | "time":{ 173 | 174 | }, 175 | "show_legend":true, 176 | "legend_size":"0" 177 | }, 178 | "layout":{ 179 | "x":49, 180 | "y":36, 181 | "width":47, 182 | "height":15 183 | } 184 | }, 185 | { 186 | "id":123456789005, 187 | "definition":{ 188 | "type":"timeseries", 189 | "requests":[ 190 | { 191 | "q":"max:system.disk.writesect.total{$host}", 192 | "display_type":"area", 193 | "style":{ 194 | "palette":"grey", 195 | "line_type":"solid", 196 | "line_width":"normal" 197 | } 198 | } 199 | ], 200 | "custom_links":[ 201 | 202 | ], 203 | "title":"System disk total write sectors", 204 | "title_size":"13", 205 | "title_align":"center", 206 | "show_legend":true, 207 | "legend_size":"0" 208 | }, 209 | "layout":{ 210 | "x":1, 211 | "y":100, 212 | "width":47, 213 | "height":15 214 | } 215 | }, 216 | { 217 | "id":123456789006, 218 | "definition":{ 219 | "type":"timeseries", 220 | "requests":[ 221 | { 222 | "q":"avg:system.disk.badblocks{$host}", 223 | "display_type":"line", 224 | "style":{ 225 | "palette":"warm", 226 | "line_type":"solid", 227 | "line_width":"thick" 228 | } 229 | } 230 | ], 231 | "custom_links":[ 232 | 233 | ], 234 | "yaxis":{ 235 | "min":"0" 236 | }, 237 | "markers":[ 238 | { 239 | "value":"y > 1", 240 | "display_type":"error dashed", 241 | "label":"Bad blocks" 242 | } 243 | ], 244 | "title":"System HDD Bad Blocks", 245 | "title_size":"13", 246 | "title_align":"center", 247 | "show_legend":true, 248 | "legend_size":"0" 249 | }, 250 | "layout":{ 251 | "x":49, 252 | "y":100, 253 | "width":47, 254 | "height":15 255 | } 256 | }, 257 | { 258 | "id":123456789007, 259 | "layout":{ 260 | "x":1, 261 | "y":2, 262 | "width":15, 263 | "height":8 264 | }, 265 | "definition":{ 266 | "title":"CPU Load", 267 | "title_size":"13", 268 | "title_align":"center", 269 | "type":"alert_value", 270 | "alert_id":"12345678904", 271 | "unit":"%", 272 | "text_align":"center", 273 | "precision":0 274 | } 275 | }, 276 | { 277 | "id":123456789008, 278 | "layout":{ 279 | "x":17, 280 | "y":2, 281 | "width":15, 282 | "height":8 283 | }, 284 | "definition":{ 285 | "title":"RAM Usage", 286 | "title_size":"13", 287 | "title_align":"center", 288 | "type":"alert_value", 289 | "alert_id":"12345678903", 290 | "unit":"%", 291 | "text_align":"center", 292 | "precision":0 293 | } 294 | }, 295 | { 296 | "id":123456789009, 297 | "definition":{ 298 | "type":"query_value", 299 | "requests":[ 300 | { 301 | "q":"avg:system.uptime{$host}", 302 | "aggregator":"last" 303 | } 304 | ], 305 | "custom_links":[ 306 | 307 | ], 308 | "title":"System Uptime", 309 | "title_size":"13", 310 | "title_align":"center", 311 | "time":{ 312 | "live_span":"1m" 313 | }, 314 | "autoscale":true, 315 | "precision":2 316 | }, 317 | "layout":{ 318 | "x":17, 319 | "y":11, 320 | "width":15, 321 | "height":8 322 | } 323 | }, 324 | { 325 | "id":123456789010, 326 | "layout":{ 327 | "x":65, 328 | "y":1, 329 | "width":31, 330 | "height":18 331 | }, 332 | "definition":{ 333 | "title":"Monitoring CPU", 334 | "title_size":"13", 335 | "title_align":"center", 336 | "time":{ 337 | "live_span":"alert" 338 | }, 339 | "type":"alert_graph", 340 | "alert_id":"12345678901", 341 | "viz_type":"timeseries" 342 | } 343 | }, 344 | { 345 | "id":123456789011, 346 | "layout":{ 347 | "x":33, 348 | "y":1, 349 | "width":31, 350 | "height":18 351 | }, 352 | "definition":{ 353 | "title":"Monitoring RAM", 354 | "title_size":"13", 355 | "title_align":"center", 356 | "time":{ 357 | "live_span":"alert" 358 | }, 359 | "type":"alert_graph", 360 | "alert_id":"12345678902", 361 | "viz_type":"timeseries" 362 | } 363 | }, 364 | { 365 | "id":123456789012, 366 | "definition":{ 367 | "type":"timeseries", 368 | "requests":[ 369 | { 370 | "q":"avg:system.health.consumption{$host}/10", 371 | "metadata":[ 372 | { 373 | "expression":"avg:system.health.consumption{$host}/10", 374 | "alias_name":"W" 375 | } 376 | ], 377 | "display_type":"line", 378 | "style":{ 379 | "palette":"warm", 380 | "line_type":"solid", 381 | "line_width":"thick" 382 | } 383 | }, 384 | { 385 | "q":"avg:system.health.current{$host}/1000", 386 | "metadata":[ 387 | { 388 | "expression":"avg:system.health.current{$host}/1000", 389 | "alias_name":"A" 390 | } 391 | ], 392 | "display_type":"line", 393 | "style":{ 394 | "palette":"cool", 395 | "line_type":"solid", 396 | "line_width":"thin" 397 | } 398 | }, 399 | { 400 | "q":"avg:system.health.voltage{$host}/10", 401 | "metadata":[ 402 | { 403 | "expression":"avg:system.health.voltage{$host}/10", 404 | "alias_name":"V" 405 | } 406 | ], 407 | "display_type":"line", 408 | "style":{ 409 | "palette":"cool", 410 | "line_type":"solid", 411 | "line_width":"thin" 412 | } 413 | } 414 | ], 415 | "yaxis":{ 416 | "label":"", 417 | "scale":"linear", 418 | "min":"auto", 419 | "max":"auto", 420 | "include_zero":true 421 | }, 422 | "title":"System Health", 423 | "title_size":"13", 424 | "title_align":"center", 425 | "time":{ 426 | 427 | }, 428 | "show_legend":true, 429 | "legend_size":"0" 430 | }, 431 | "layout":{ 432 | "x":1, 433 | "y":52, 434 | "width":47, 435 | "height":23 436 | } 437 | }, 438 | { 439 | "id":123456789013, 440 | "definition":{ 441 | "type":"timeseries", 442 | "requests":[ 443 | { 444 | "q":"avg:system.health.fanspeed.1{$host}", 445 | "metadata":[ 446 | { 447 | "expression":"avg:system.health.fanspeed.1{$host}", 448 | "alias_name":"RPM" 449 | } 450 | ], 451 | "display_type":"line", 452 | "style":{ 453 | "palette":"dog_classic", 454 | "line_type":"solid", 455 | "line_width":"normal" 456 | } 457 | }, 458 | { 459 | "q":"avg:system.health.fanspeed.2{$host}", 460 | "metadata":[ 461 | { 462 | "expression":"avg:system.health.fanspeed.2{$host}", 463 | "alias_name":"RPM" 464 | } 465 | ], 466 | "display_type":"line", 467 | "style":{ 468 | "palette":"dog_classic", 469 | "line_type":"solid", 470 | "line_width":"normal" 471 | } 472 | } 473 | ], 474 | "yaxis":{ 475 | "label":"", 476 | "scale":"linear", 477 | "min":"auto", 478 | "max":"auto", 479 | "include_zero":true 480 | }, 481 | "title":"FAN Speed", 482 | "title_size":"13", 483 | "title_align":"center", 484 | "time":{ 485 | 486 | }, 487 | "show_legend":true, 488 | "legend_size":"0" 489 | }, 490 | "layout":{ 491 | "x":49, 492 | "y":76, 493 | "width":47, 494 | "height":23 495 | } 496 | }, 497 | { 498 | "id":123456789014, 499 | "definition":{ 500 | "type":"timeseries", 501 | "requests":[ 502 | { 503 | "q":"avg:system.health.temperature{$host}", 504 | "metadata":[ 505 | { 506 | "expression":"avg:system.health.temperature{$host}", 507 | "alias_name":"°C" 508 | } 509 | ], 510 | "display_type":"line", 511 | "style":{ 512 | "palette":"dog_classic", 513 | "line_type":"solid", 514 | "line_width":"normal" 515 | } 516 | }, 517 | { 518 | "q":"avg:system.health.temperature.cpu{$host}", 519 | "metadata":[ 520 | { 521 | "expression":"avg:system.health.temperature.cpu{$host}", 522 | "alias_name":"°C" 523 | } 524 | ], 525 | "display_type":"line", 526 | "style":{ 527 | "palette":"dog_classic", 528 | "line_type":"solid", 529 | "line_width":"normal" 530 | } 531 | } 532 | ], 533 | "yaxis":{ 534 | "label":"", 535 | "scale":"linear", 536 | "min":"auto", 537 | "max":"auto", 538 | "include_zero":true 539 | }, 540 | "title":"Temperature", 541 | "title_size":"13", 542 | "title_align":"center", 543 | "time":{ 544 | 545 | }, 546 | "show_legend":true, 547 | "legend_size":"0" 548 | }, 549 | "layout":{ 550 | "x":1, 551 | "y":76, 552 | "width":47, 553 | "height":23 554 | } 555 | }, 556 | { 557 | "id":123456789015, 558 | "definition":{ 559 | "type":"timeseries", 560 | "requests":[ 561 | { 562 | "q":"avg:system.uptime{$host}", 563 | "display_type":"line", 564 | "style":{ 565 | "palette":"dog_classic", 566 | "line_type":"solid", 567 | "line_width":"normal" 568 | } 569 | } 570 | ], 571 | "yaxis":{ 572 | "label":"", 573 | "scale":"linear", 574 | "min":"auto", 575 | "max":"auto", 576 | "include_zero":true 577 | }, 578 | "title":"System Uptime", 579 | "title_size":"13", 580 | "title_align":"center", 581 | "time":{ 582 | 583 | }, 584 | "show_legend":true, 585 | "legend_size":"0" 586 | }, 587 | "layout":{ 588 | "x":49, 589 | "y":52, 590 | "width":47, 591 | "height":23 592 | } 593 | }, 594 | { 595 | "id":123456789016, 596 | "layout":{ 597 | "x":1, 598 | "y":11, 599 | "width":15, 600 | "height":8 601 | }, 602 | "definition":{ 603 | "title":"Temperature", 604 | "title_size":"13", 605 | "title_align":"center", 606 | "type":"alert_value", 607 | "alert_id":"11563128", 608 | "unit":"°C", 609 | "text_align":"center", 610 | "precision":2 611 | } 612 | } 613 | ], 614 | "template_variables":[ 615 | { 616 | "name":"host", 617 | "default":"*", 618 | "prefix":"host" 619 | } 620 | ], 621 | "layout_type":"free", 622 | "is_read_only":false, 623 | "notify_list":[ 624 | 625 | ], 626 | "id":"xxx-xxx-xxx" 627 | } -------------------------------------------------------------------------------- /datadog-public-dashboard-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtrimarchi/MikrotikJSON4DatadogAPI/6851761a4ac045be26bfef93a3eed29cdeca6cdb/datadog-public-dashboard-example.png --------------------------------------------------------------------------------