Developing lightweight computation at the DSG edge

README.md 20.2 KB
Newer Older
1
2
# uc-monitor-go-test [![Go Report Card](https://goreportcard.com/badge/lightkone.guifi.net/lightkone/uc-monitor-go-test)](https://goreportcard.com/report/lightkone.guifi.net/lightkone/uc-monitor-go-test)

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
3
An initial implementation, in the form of microservices, of a distributed, decentralised and resilient monitoring system for the Guifi.net network nodes. It uses [AntidoteDB](https://syncfree.github.io/antidote/) and is part of the [LightKone](https://www.lightkone.eu/) project.
felix's avatar
felix committed
4

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
5
6
## Description
The monitoring application is distributed in three main blocks:
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
7
8
9
10
11
 - Network description fetching and feeding: functional
 - Automated nodes assignment among the different monitoring servers: functional
 - Actual nodes monitorisation
  - Uptime: functional
  - SNMP: WiP
felix's avatar
felix committed
12

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
13
14
15
16
This implementation uses [Mathias Weber (@mweberUKL)](https://github.com/mweberUKL)'s Go client for AntidoteDB.

This document briefly explains the applications, how to run them and how the data are structured.
It takes advantage of the [AntidoteDB Java tutorial](https://github.com/SyncFree/antidote-java-tutorial) by [Deepthi Akkoorath (@deepthidevaki)](https://github.com/deepthidevaki) and [João Neto (@joaomlneto)](https://github.com/joaomlneto)'s [HTTP/HTTPS REST API for AntidoteDB](https://github.com/LightKone/antidote-rest-server).
felix's avatar
felix committed
17

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
18
## Installation
felix's avatar
felix committed
19

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
20
### Docker
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
21
Install `docker-ce` using your preferred method as [described here](https://docs.docker.com/install/).
felix's avatar
felix committed
22

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
23
24
### Go and required libraries
Install Go using your operating system's package manager or follow the [instructions here](https://golang.org/doc/install).
felix's avatar
felix committed
25

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
26
27
After installing Go, download and install the folowing external libraries needed:
 - golang/glog:
felix's avatar
felix committed
28

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
29
 `go get github.com/golang/glog`
felix's avatar
felix committed
30

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
31
 - sparrc/go-ping:
felix's avatar
felix committed
32

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
33
 `go get github.com/sparrc/go-ping`
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
34

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
35
- antidote-go-client:
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
36

felix's avatar
felix committed
37
 `go get github.com/AntidoteDB/antidote-go-client`
felix's avatar
felix committed
38

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
39
40
41
42
43
### AntidoteDB Java tutorial
Get the tutorial's source code [here](https://github.com/SyncFree/antidote-java-tutorial) to download the code and [start the two AntidoteDB nodes](https://github.com/SyncFree/antidote-java-tutorial#starting-antidote-nodes).

### HTTP/HTTPS REST API

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
44
The AntidoteDB REST API server is no longer used by the monitoring applications, but it comes handy to perform quick tests like the ones in this document. You can follow the [instructions here](https://github.com/LightKone/antidote-rest-server) to install it..
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
45

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
46
## Running the application
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
47
48

### Fetch the network description and feed it to AntidoteDB
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
49
50
The Guifi-UPC network (a small fraction of the whole Guifi.net) description file is included in `assets/cnml/upc.xml` and is used by default. The `monitor-fetch` program fetches the data from the file and pushes it to AntidoteDB:
```bash
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
51
52
$ cd src/monitor/fetch/
$ go run monitor-fetch.go
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
53
54
55
56
57
58
59
60
61
62
63
64
19 nodes read from ../assets/cnml/upc.xml
63 devices read from ../assets/cnml/upc.xml
54 devices exported to /tmp/gmonitor2/devs.json

16 devices removed from AntidoteDB (0 success, 0 fail)
16 graphservers removed from AntidoteDB (0 success, 0 fail)
27 IPv4 addresses removed from AntidoteDB (0 success, 0 fail)

54 devices added to AntidoteDB (54 success, 0 fail)
54 graphservers added or updated to AntidoteDB (54 success, 0 fail)
67 IPv4 addresses added or updated to AntidoteDB (67 success, 0 fail)

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
65
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
66
67
Other small sub-networks' descriptions are available in the `assets/cnml` folder, some of them overlapping and some not.

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
68
Beyond the development and testing phase, the whole Guifi.net CNML description can be loaded (warning, it's HUGE, and it's GROWING):
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
69
70
71
72
73
74
75
```bash
$ go run monitor-fetch.go -cnml_file ../assets/cnml/guifi.xml

57642 nodes read from ../assets/cnml/guifi.xml
53461 devices read from ../assets/cnml/guifi.xml
39988 devices exported to /tmp/gmonitor2/devs.json

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
76
0 devices removed from AntidoteDB (0 success, 0 fail)
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
77
0 graphservers removed from AntidoteDB (0 success, 0 fail)
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
78
79
0 IPv4 addresses removed from AntidoteDB (0 success, 0 fail)

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
80
81
82
39988 devices added to AntidoteDB (39988 success, 0 fail)
39988 graphservers added or updated to AntidoteDB (39988 success, 0 fail)
49671 IPv4 addresses added or updated to AntidoteDB (49671 success, 0 fail)
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
83
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
84
85
86
87
88
89
90
91
92
93

### Assign network nodes to monitoring servers
Each monitoring instance consists of three pieces of code, `monitor-assign`, `monitor-ping` and `monitor-snmp`. Eventually they will be merged into a single one encompassing all the functions.

The `monitor-assign` program gets the whole Guifi.net network description from AntidoteDB, checks which devices are not being monitored (or are not being monitored with enough redundancy) and randomly picks some of them to start monitoring them.
In the future, this random picking will be replaced by a smarter algorithm.
Different options can be specified, like the monitor's `ID`, the maximum number of devices to take care of monitoring, the minimum redundancy, etc.:
<details><summary><b>$ go run monitor-assign.go -id 12345 -maxDevs 5 -minMons 3</b> (click here to see the whole content)</summary>
<p>

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
94
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
Initializing...
Using ID 12345
Setting timestamp to 1560419260
Updating globalAssign...
Adding device 35578 from cnmlDevices into globalAssign
Adding device 35580 from cnmlDevices into globalAssign
Adding device 41236 from cnmlDevices into globalAssign
Adding device 52800 from cnmlDevices into globalAssign
Adding device 53410 from cnmlDevices into globalAssign
Adding device 55625 from cnmlDevices into globalAssign
Adding device 58266 from cnmlDevices into globalAssign
Adding device 66287 from cnmlDevices into globalAssign
Adding device 67954 from cnmlDevices into globalAssign
Adding device 69514 from cnmlDevices into globalAssign
Adding device 74780 from cnmlDevices into globalAssign
Adding device 74943 from cnmlDevices into globalAssign
Adding device 75036 from cnmlDevices into globalAssign
Adding device 75038 from cnmlDevices into globalAssign
Adding device 75651 from cnmlDevices into globalAssign
Adding device 92844 from cnmlDevices into globalAssign
globalAssign updated!
Initialization done. Entering infinite loop...
Setting timestamp to 1560419265

Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!

Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Ended assignation list sanitization...

Reassignation of devices
0 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
16 devices unassigned
Picking 1 nodes randomly
1 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419270

Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!

Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Ended assignation list sanitization...

Reassignation of devices
1 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
15 devices unassigned
Picking 1 nodes randomly
2 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419275

Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!

Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75651
Ended assignation list sanitization...

Reassignation of devices
2 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
14 devices unassigned
Picking 1 nodes randomly
3 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419280

Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!

Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75036
Monitor 12345 found, keeping it for device 75651
Ended assignation list sanitization...

Reassignation of devices
3 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
13 devices unassigned
Picking 1 nodes randomly
4 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419285

Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!

Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75036
Monitor 12345 found, keeping it for device 75038
Monitor 12345 found, keeping it for device 75651
Ended assignation list sanitization...

Reassignation of devices
4 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
12 devices unassigned
Picking 1 nodes randomly
5 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419290

Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!

Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75036
Monitor 12345 found, keeping it for device 75038
Monitor 12345 found, keeping it for device 75651
Monitor 12345 found, keeping it for device 92844
Ended assignation list sanitization...

Reassignation of devices
5 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Not assigning any new device
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
260
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
261
262
263
264
265
266
267
268
</p>
</details>

<p>

`monitor-assign` not only cares about assigning itself the devices to monitor, but also pushes this information to AntidoteDB, so that other monitors can indirectly coordinate and pick the right devices to monitor.
Additionally, it periodically sanitizes the global assignation in AntidoteDB, by pruning assignations from monitors that are not in the system anymore (crashed, unresponsive, in another network partition...)

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
269
### Monitor the nodes' liveliness (ping RTT and TTL)
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
270
271
272
273
274
275
276
The `monitor-ping` pings the different devices the monitor is assigned periodically, and writes the information to AntidoteDB.
To have enough resolution for graphing, each device must be pinged *at least* every five minutes (and, ideally, this will happen simultaneously in other monitors, achieving the required redundancy).
The `monitor-ping` instance **must** use the same `ID` parameter as the local `monitor-assign` instance (in the future they will be merged into a single process):

<details><summary><b>$ go run monitor-ping.go -id 12345</b> (click here to see the whole content)</summary>
<p>

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
277
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
Initializing...
Using ID 12345
Initialization done. Entering infinite loop...
Pinging devices...
Pinging device 101994
10.1.27.13
I was asked to ping 10.1.27.13
false ==> offline
Pinging device 38720
10.1.26.97
I was asked to ping 10.1.26.97
true ==> online
Pinging device 42628
10.1.25.225
I was asked to ping 10.1.25.225
true ==> online
Pinging device 83865
10.1.25.130
10.228.207.130
I was asked to ping 10.1.25.130
true ==> online
Pinging device 87503
10.1.25.194
I was asked to ping 10.1.25.194
true ==> online
Pinging devices...
Pinging device 101994
10.1.27.13
I was asked to ping 10.1.27.13
false
Pinging device 38720
10.1.26.97
I was asked to ping 10.1.26.97
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
311
312

```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
313
314
315
316
317
318
319
320
321
</p>
</details>


#### Note
Prior to running the program, a system setting must be configured:

```bash
$ sudo sysctl -w net.ipv4.ping_group_range="0 2147483647"
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
322
323
```

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
324
325
as per this note on Linux support:

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
326
```[...] this library attempts to send an "unprivileged" ping via UDP. On Linux, this must be enabled by setting [...]```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
327
328
329
330
331
332
333
334
335

### Monitor the nodes' network traffic (SNMP) [WiP]
The `monitor-snmp` periodically asks the different devices the monitor is assigned periodically for their [SNMP information](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol) to get details about their interfaces and the inbound/outbound traffic.
To have enough resolution for graphing, each device must be probed *at least* every five minutes (and, ideally, this will happen simultaneously in other monitors, achieving the required redundancy).
The `monitor-snmp` instance **must** use the same `ID` parameter as the local `monitor-assign` instance (in the future they will be merged into a single process).

Development of this piece of code is WiP.


Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
336
337
338

## Data structures in AntidoteDB

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
339
### Devices⇔Monitors assignation
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
340
341
The primary data source for this application is the CNML file. The `monitor-fetch` application parses the specified CNML file and pushes its contents to AntidoteDB. There is a single `monitor-fetch` instance, and its writes/updates are __authoritative__.

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
342
In AntidoteDB, the data are structured as follows (some structures are shared with the *Monitoring data*, described below):
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
343
344

#### guifi (bucket)
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
345
The `guifi` bucket contains the lists of monitors and network devices to be monitored:
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
346
347
348
349
350
351
352
353
354
355
356
##### guifi (bucket) => devices (set)
The `devices` *set* in the `guifi` *bucket* is an `array` of `strings`, each `string` containing the `ID` of a Guifi.net device. For example:
```bash
$ curl localhost:3000/set/read/guifi/devices
  ["22110","26932","38720","40605","40962","41175","42331","42626","42627","42628",
   "46654","46656","47103","48030","51580","57728","59001","60415","64962","64963",
   "64965","64966","65291","65720","72843","73952","79715","81297","82096","82097",
   "82098","82099","82103","82104","82105","82111","83865","85877","87503","90228",
   "92032","92802","92803","92804","94210","94965","96225","96676","96684"]
```

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
357
358
359
360
##### guifi (bucket) => monitors (set)
The `monitors` *set* in the `guifi` *bucket* is an `array` of `strings`, each `string` containing the `ID` of a Guifi.net monitor. For example:
```bash
$ curl localhost:3000/set/read/guifi/monitors
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
361
  ["a45632","a47363", "21435"]
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
362
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
363
When started, each of the monitoring instances register to the system by adding their `ID` to this *set*.
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
364

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
365
366
367
368
369
370
##### guifi (bucket) => checksum (LWW<sup>1</sup> register)
The `checksum` *LWW register* in the `guifi` *bucket* is a `strings` containing the *SHA256 checksum* of the CNML data fetched from the Guifi.net website and pushed to the database. For example:
```bash
$ curl localhost:3000/register/read/guifi/checksum
  35aaa826b841ed412897691bb1f50278d742ef9a76da9750a8ae509d3b01f8ee
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
371

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#### device-i (bucket)
The `device-i` bucket, where `i` is the numeric `ID` of a device in the `guifi/devices` set, contains the information about a Guifi.net device:

##### device-i (bucket) => ipv4s (set)
The `ipv4s` *set* in the `device-i` *bucket* is an `array` of `strings`, each `string` containing an IPv4 address of the device. For example:
```bash
$ curl localhost:3000/set/read/device-26932/ipv4s
  ["10.139.37.226","172.25.40.188","172.25.40.189"]
```

##### device-i (bucket) => monitors (set)
The `monitors` *set* in the `device-i` *bucket* is an `array` of `strings`, each `string` containing the ID of a monitor the device is assigned to (i.e. the `ID` of a monitor that is in charge of monitoring the device). For example:
```bash
$ curl localhost:3000/set/read/device-26932/monitors
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
386
  ["a45632","a47363","21435"]
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
387
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
388
389

##### device-i (bucket) => graphserver (LWW register)
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
390
391
392
393
394
395
396
The `graphserver` *LWW register* in the `device-i` *bucket* is a `string` containing the ID of a monitor the device is assigned to **in the Guifi.net** website (i.e., not automatically assigned by the monitoring application, but done manually on the Guifi.net website, and included in the CNML). For example:

```bash
$ curl localhost:3000/register/read/device-26932/graphserver
  71808
```

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
397
398
399
400
401
402
403
404
405
406
407
408
409

### Monitoring data
The collected monitoring data are stored in AntidoteDB using the following structure and data types (some structures are shared with the *Devices⇔Monitors assignation* sata, described above:

#### device-i (bucket)
The `device-i` bucket, where `i` is the numeric `ID` of a device in the `guifi/devices` set, contains the monitoring data collected about a Guifi.net device:

##### device-i (bucket) => rawping (map)
The `rawping` *map* in the `device-i` *bucket* is a collection of nested maps where the raw ping data are stored.

The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawping/
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
410
  {["2018-12-31","2019-01-01","2019-01-02","2019-01-03","2019-01-04","2019-01-05","2019-01-06", ... ,"2019-03-13","2019-03-14"]}
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
411
412
```

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
413
414
##### device-i (bucket) => rawping (map) => year-month-day (map)
The `year-month-day` *map* in the `rawping` *map* in the `device-i` *bucket* contains the raw ping data stored during a given day.
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
415
416
417

The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
418
419
$ curl localhost:3000/map/list/device-26932/rawping/2019-03-14/
  {["00-00-00-21435","00-00-00-a45632","00-00-00-a47363","00-05-00-21435","00-05-00-a45632","00-05-00-a47363","00-10-00-21435","00-10-00-a45632","00-10-00-a47363","23-50-00-21435","23-50-00-a45632","23-50-00-a47363","23-55-00-21435","23-55-00-a45632","23-55-00-a47363"]}
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
420
421
```

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
422
423
##### device-i (bucket) => rawping (map) => year-month-day (map) => hour-minute-second-monitorID (set)
The `year-month-day` *map* in the `rawping` *map* in the `device-i` *bucket* contains the raw ping data captured at a given moment by a specific monitor.
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
424
425
426

The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
427
428
$ curl localhost:3000/map/list/device-26932/rawping/2019-03-14/23-55-00-a45632
  {["12452","9873","10347","12906","96991","62"]}
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
429
```
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
430
where the 5 first numbers correspond to the ping RTT, in nanoseconds, and the last one to the TTL count.
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
431

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
##### device-i (bucket) => rawsnmp (map)
The `rawsnmp` *map* in the `device-i` *bucket* is a collection of nested maps where the raw SNMP data are stored.

The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawsnmp/
  {["2018-12-31","2019-01-01","2019-01-02","2019-01-03","2019-01-04","2019-01-05","2019-01-06", ... ,"2019-03-13","2019-03-14"]}
```

##### device-i (bucket) => rawsnmp (map) => year-month-day (map)
The `year-month-day` *map* in the `rawsnmp` *map* in the `device-i` *bucket* contains the raw SNMP data stored during a given day.

The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawsnmp/2019-03-14/
  {["00-00-00-21435","00-00-00-a45632","00-00-00-a47363","00-05-00-21435","00-05-00-a45632","00-05-00-a47363","00-10-00-21435","00-10-00-a45632","00-10-00-a47363","23-50-00-21435","23-50-00-a45632","23-50-00-a47363","23-55-00-21435","23-55-00-a45632","23-55-00-a47363"]}
```

##### device-i (bucket) => rawping (map) => year-month-day (map) => hour-minute-second-monitorID (set)
The `year-month-day` *map* in the `rawsnmp` *map* in the `device-i` *bucket* contains the raw SNMP data captured at a given moment by a specific monitor.

The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawsnmp/2019-03-14/23-55-00-a45632
  {["sfp1", "0", "320", "ether1", "0", "0", "wlan1", "72752170", "194023223",
  "ether3", "4211890690", "3457835469", "ether4", "1481996123", "3715009965",
  "ether5", "3986712032", "2292081157", "ether6", "6036", "43256812", "wlan5",
  "3253125075", "4192397953", "wlan6", "1438160383", "430948927", "ether9", "0",
  "0", "ether10", "0", "0", "lan", "75134070", "158936718", "wlan2", "0", "0",
  "wlan3", "1224542542", "3312721186", "wlan4", "0", "6703436", "sjd",
  "166864741", "6605882", "bel", "0", "6605882", "qmp", "0", "0", "wlan7",
  "2064155005", "1601779739"]}
```
where the data are ordered, sequentially, as "Interface name", "RxBytes", "TxBytes", etc.

Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
467
---
Roger Pueyo Centelles's avatar
Roger Pueyo Centelles committed
468
469
<sup>1</sup> LWW: last writer wins  
<sup>2</sup> The REST API does not support nested maps (but the Go client does)