parent
69079b7d64
commit
f423da31d2
|
@ -0,0 +1,5 @@
|
|||
## Contributing is welcome
|
||||
|
||||
Pull requests are welcome without the need of opening an issue. If you're unsure
|
||||
about your feature or your implementation open an issue and discuss your
|
||||
suggested changes.
|
|
@ -0,0 +1,16 @@
|
|||
<!--- Use a prefix like [TASK], [BUGFIX], [DOC] or [TEST] and provide a general summary of your changes in the Title above -->
|
||||
|
||||
## Description
|
||||
<!--- Describe your changes -->
|
||||
|
||||
## Motivation and Context
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
## Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] My code follows the code style of this project.
|
||||
- [ ] I have added also tests for my new code.
|
||||
- [ ] My change requires a change to the documentation.
|
||||
- [ ] I have updated the documentation accordingly.
|
|
@ -30,4 +30,22 @@ if [ "$FAIL" -eq 0 ]; then
|
|||
bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN -f profile.cov
|
||||
fi
|
||||
|
||||
# Test if every package has testfiles
|
||||
for dir in $(find . -name "*.go" -printf '%h\0'| sort -zu | sed -z 's/$/\n/');
|
||||
do
|
||||
if [ "$(ls $dir/*_test.go 2> /dev/null | wc -l)" -eq "0" ]; then
|
||||
echo -n "no test files for $dir";
|
||||
case $dir in
|
||||
'.' | './cmd' | './database/graphite')
|
||||
echo " - but ignored";
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
echo "";
|
||||
FAIL=1;
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
|
||||
exit $FAIL
|
||||
|
|
15
INSTALL.md
15
INSTALL.md
|
@ -1,12 +1,13 @@
|
|||
# Howto install Yanic
|
||||
|
||||
## go
|
||||
|
||||
### Install
|
||||
```sh
|
||||
cd /usr/local/
|
||||
wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
|
||||
tar xvf go1.8.linux-amd64.tar.gz
|
||||
rm go1.8.linux-amd64.tar.gz
|
||||
wget https://storage.googleapis.com/golang/go1.9.1.linux-amd64.tar.gz -O go-release-linux-amd64.tar.gz
|
||||
tar xvf go-release-linux-amd64.tar.gz
|
||||
rm go-release-linux-amd64.tar.gz
|
||||
```
|
||||
|
||||
### Configure go
|
||||
|
@ -16,12 +17,6 @@ export GOPATH=/opt/go
|
|||
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
|
||||
```
|
||||
|
||||
and these in the shell startup file of a normal user:
|
||||
```sh
|
||||
export GOPATH=~/go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
```
|
||||
|
||||
## Yanic
|
||||
|
||||
### Compile
|
||||
|
@ -65,7 +60,7 @@ the same directory as the `dataPath`. Change the path in the section
|
|||
|
||||
### Service
|
||||
```sh
|
||||
cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/
|
||||
cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/yanic.service
|
||||
systemctl daemon-reload
|
||||
systemctl start yanic
|
||||
systemctl enable yanic
|
||||
|
|
|
@ -24,11 +24,9 @@ Yet another node info collector
|
|||
In the first step Yanic sends a multicast message to the group `ff02:0:0:0:0:0:2:1001` and port `1001`.
|
||||
Recently seen nodes that does not reply are requested via a unicast message.
|
||||
|
||||
## [Documentation](https://www.gitbook.com/book/freifunkbremen/yanic/details)
|
||||
* [Webview](https://freifunkbremen.gitbooks.io/yanic/content/)
|
||||
* [PDF](https://www.gitbook.com/download/pdf/book/freifunkbremen/yanic)
|
||||
* [Mobi](https://www.gitbook.com/download/mobi/book/freifunkbremen/yanic)
|
||||
* [ePUB](https://www.gitbook.com/download/epub/book/freifunkbremen/yanic)
|
||||
## Documentation
|
||||
Take a look at the [git](https://github.com/FreifunkBremen/yanic/blob/master/SUMMARY.md) or [Gitbook](https://freifunkbremen.gitbooks.io/yanic/content/)
|
||||
|
||||
|
||||
## Configuration
|
||||
Read comments in [config_example.toml](config_example.toml) for more information.
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# Summary
|
||||
|
||||
* [Home](/docs/index.md)
|
||||
* [About](/docs/home_about.md)
|
||||
* [Running](/docs/home_running.md)
|
||||
|
||||
* Documentation
|
||||
* [Build and Install](/docs/docs_install.md)
|
||||
* [Usage](/docs/docs_usage.md)
|
||||
* [Quick Configuration](/docs/docs_quick_conf.md)
|
||||
* [Configuration](/docs/docs_configuration.md)
|
||||
|
||||
* Developing
|
||||
* [Add new database type](/docs/dev_database.md)
|
||||
* [Add new output type](/docs/dev_output.md)
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"plugins": [
|
||||
"theme-api",
|
||||
"anchors",
|
||||
"sitemap"
|
||||
],
|
||||
"pluginsConfig": {
|
||||
"theme-api": {
|
||||
"split": true,
|
||||
"languages": [
|
||||
{
|
||||
"lang": "toml",
|
||||
"name": "TOML",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"sitemap": {
|
||||
"hostname": "https://freifunkbremen.gitbooks.io/yanic/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
# This is the config file for Yanic written in "Tom's Obvious, Minimal Language."
|
||||
# syntax: https://github.com/toml-lang/toml
|
||||
# (if you need somethink multiple times, checkout out the [[table]] section)
|
||||
# (if you need somethink multiple times, checkout out the [[array of table]] section)
|
||||
|
||||
# Send respondd request to update information
|
||||
[respondd]
|
||||
|
@ -27,7 +27,6 @@ webroot = "/var/www/html/meshviewer"
|
|||
|
||||
|
||||
[nodes]
|
||||
enable = true
|
||||
# Cache file
|
||||
# a json file to cache all data collected directly from respondd
|
||||
state_path = "/var/lib/yanic/state.json"
|
||||
|
@ -138,17 +137,12 @@ password = ""
|
|||
# Tagging of the data (optional)
|
||||
[database.connection.influxdb.tags]
|
||||
# Tags used by Yanic would override the tags from this config
|
||||
# nodeid, hostname, owner, model and firmware are tags which are already used
|
||||
# nodeid, hostname, owner, model, firmware_base, firmware_release,frequency11g and frequency11a are tags which are already used
|
||||
#tagname1 = "tagvalue 1"
|
||||
# some usefull e.g.:
|
||||
#system = "productive"
|
||||
#site = "ffhb"
|
||||
|
||||
# Logging
|
||||
[[database.connection.logging]]
|
||||
enable = false
|
||||
path = "/var/log/yanic.log"
|
||||
|
||||
# Graphite settings
|
||||
[[database.connection.graphite]]
|
||||
enable = false
|
||||
|
@ -160,3 +154,8 @@ address = "localhost:2003"
|
|||
# then the prefix can be set to anything (including the empty string) since you
|
||||
# probably wont care much about "polluting" the namespace.
|
||||
prefix = "freifunk"
|
||||
|
||||
# Logging
|
||||
[[database.connection.logging]]
|
||||
enable = false
|
||||
path = "/var/log/yanic.log"
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Add new database type
|
||||
|
||||
Write a new package to implement the interface [database.Connection:](https://github.com/FreifunkBremen/yanic/blob/master/database/database.go)
|
||||
|
||||
```go
|
||||
type Connection interface {
|
||||
InsertNode(node *runtime.Node)
|
||||
|
||||
InsertLink(*runtime.Link, time.Time)
|
||||
|
||||
InsertGlobals(*runtime.GlobalStats, time.Time, string)
|
||||
|
||||
PruneNodes(deleteAfter time.Duration)
|
||||
|
||||
Close()
|
||||
}
|
||||
```
|
||||
|
||||
**InsertNode** is stores statistics per node
|
||||
|
||||
**InsertLink** is stores statistics per link
|
||||
|
||||
**InsertGlobals** is stores global statistics (by `site_code`, and "global" like in `runtime.GLOBAL_SITE` overall sites).
|
||||
|
||||
**PruneNodes** is prunes historical per-node data
|
||||
|
||||
**Close** is called during shutdown of Yanic.
|
||||
|
||||
|
||||
|
||||
For startup, you need to bind your database type by calling `database.RegisterAdapter("typeofdatabase",ConnectFunction)`
|
||||
|
||||
it should be in the `func init() {}` of your package.
|
||||
|
||||
|
||||
|
||||
The _typeofdatabase_ is used as mapping in the configuration `[[database.connection.typeofdatabase]]` the `map[string]interface{}` of the content are parsed to the _ConnectFunction_ and on of your implemented `Connection` or a `error` is needed as result.
|
||||
|
||||
|
||||
|
||||
Short: the function signature of _ConnectFunction_ should be `func Connect(configuration interface{}) (Connection, error)`
|
||||
|
||||
|
||||
|
||||
At last add you import string to compile the your database as well in this [all](https://github.com/FreifunkBremen/yanic/blob/master/database/all/main.go) package.
|
||||
|
||||
|
||||
|
||||
TIP: take a look in the easy database type [logging](https://github.com/FreifunkBremen/yanic/blob/master/database/logging/file.go).
|
|
@ -0,0 +1,30 @@
|
|||
# Add new output type
|
||||
|
||||
Write a new package to implement the interface [output.Output:](https://github.com/FreifunkBremen/yanic/blob/master/output/output.go)
|
||||
|
||||
```go
|
||||
type Output interface {
|
||||
Save(nodes *runtime.Nodes)
|
||||
}
|
||||
```
|
||||
|
||||
**Save** a pre-filtered state of the Nodes
|
||||
|
||||
|
||||
|
||||
For startup, you need to bind your output type by calling
|
||||
`output.RegisterAdapter("typeofoutput",Register)`
|
||||
|
||||
it should be in the `func init() {}` of your package.
|
||||
|
||||
|
||||
|
||||
The _typeofoutput_ is used as mapping in the configuration `[[nodes.output.typeofoutput]]` the `map[string]interface{}` of the content are parsed to the _Register_ and on of your implemented `Output` or a `error` is needed as result.
|
||||
|
||||
|
||||
|
||||
Short: the function signature of _Register_ should be `func Register(configuration map[string]interface{}) (Output, error)`
|
||||
|
||||
|
||||
|
||||
At last add you import string to compile the your database as well in this [all](https://github.com/FreifunkBremen/yanic/blob/master/output/all/main.go) package.
|
|
@ -0,0 +1,585 @@
|
|||
# Configuration
|
||||
|
||||
Here you would find a long description, maybe the description in [example file](https://github.com/FreifunkBremen/yanic/blob/master/config_example.toml) are enough for you.
|
||||
|
||||
The config file for Yanic written in "Tom's Obvious, Minimal Language." [syntax](https://github.com/toml-lang/toml).
|
||||
(if you need somethink multiple times, checkout out the [[array of table]] section)
|
||||
|
||||
## [respondd]
|
||||
{% method %}
|
||||
Group for configuration of respondd request.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[respondd]
|
||||
enable = true
|
||||
# synchronize = "1m"
|
||||
collect_interval = "1m"
|
||||
interfaces = ["br-ffhb"]
|
||||
sites = ["ffhb"]
|
||||
#port = 10001
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### enable
|
||||
{% method %}
|
||||
Enable request and collection of data per respondd requests
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = true
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### synchronize
|
||||
{% method %}
|
||||
Delay startup until a multiple of the period since zero time
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
synchronize = "1m"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### collect_interval
|
||||
{% method %}
|
||||
How often send request per respondd.
|
||||
|
||||
It will send UDP packets with multicast group `ff02::2:1001` and port `1001`.
|
||||
If a node does not answer after the half time, it will request with the last know address under the port `1001`.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
collect_interval = "1m"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### interfaces
|
||||
{% method %}
|
||||
Interface that has an IP in your mesh network
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
interfaces = ["br-ffhb"]
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### sites
|
||||
{% method %}
|
||||
List of sites to save stats for (empty for global only)
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
sites = ["ffhb"]
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### port
|
||||
{% method %}
|
||||
Define a port to listen and send the respondd packages.
|
||||
If not set or set to 0 the kernel will use a random free port at its own.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
port = 10001
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [webserver]
|
||||
{% method %}
|
||||
Yanic has a little build-in webserver, which statically serves a directory.
|
||||
This is useful for testing purposes or for a little standalone installation.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[webserver]
|
||||
enable = false
|
||||
bind = "127.0.0.1:8080"
|
||||
webroot = "/var/www/html/meshviewer"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### enable
|
||||
{% method %}
|
||||
Enable to start the built-in webserver of Yanic
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = false
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### bind
|
||||
{% method %}
|
||||
On which ip address and port listen the webserver
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
bind = "127.0.0.1:8080"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### webroot
|
||||
{% method %}
|
||||
The path to a folder, which files are published on this webserver.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
webroot = "/var/www/html/meshviewer"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [nodes]
|
||||
{% method %}
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[nodes]
|
||||
state_path = "/var/lib/yanic/state.json"
|
||||
prune_after = "7d"
|
||||
save_interval = "5s"
|
||||
offline_after = "10m"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### state_path
|
||||
{% method %}
|
||||
A json file to cache all data collected directly from respondd.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
state_path = "/var/lib/yanic/state.json"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### prune_after
|
||||
{% method %}
|
||||
Prune data in RAM, cache-file and output json files (i.e. nodes.json) that were inactive for longer than.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
prune_after = "7d"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### save_interval
|
||||
{% method %}
|
||||
Export nodes and graph periodically.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
save_interval = "5s"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### offline_after
|
||||
{% method %}
|
||||
Set node to offline if not seen within this period.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
offline_after = "10m"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
## [[nodes.output.example]]
|
||||
{% method %}
|
||||
This example block shows all option which is useable for every following output type.
|
||||
Every output type has his own configuration under `nodes.output`.
|
||||
It is possible to have multiple output for one type of output, just add this group again with new parameters (see toml [[array of table]]).
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[[nodes.output.example]]
|
||||
enable = true
|
||||
[nodes.output.example.filter]
|
||||
no_owner = true
|
||||
blacklist = ["00112233445566", "1337f0badead"]
|
||||
has_location = true
|
||||
[nodes.output.example.filter.in_area]
|
||||
latitude_min = 34.30
|
||||
latitude_max = 71.85
|
||||
longitude_min = -24.96
|
||||
longitude_max = 39.72
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
### enable
|
||||
{% method %}
|
||||
Each output format has its own config block and needs to be enabled by adding:
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = true
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
### [nodes.output.example.filter]
|
||||
{% method %}
|
||||
For each output format there can be set different filters
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[nodes.output.example.filter]
|
||||
no_owner = true
|
||||
blacklist = ["00112233445566", "1337f0badead"]
|
||||
has_location = true
|
||||
[nodes.output.example.filter.in_area]
|
||||
latitude_min = 34.30
|
||||
latitude_max = 71.85
|
||||
longitude_min = -24.96
|
||||
longitude_max = 39.72
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### no_owner
|
||||
{% method %}
|
||||
Set to false, if you want the json files to contain the owner information
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
no_owner = true
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### blacklist
|
||||
{% method %}
|
||||
List of nodeids of nodes that should be filtered out, so they won't appear in output
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
blacklist = ["00112233445566", "1337f0badead"]
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### has_location
|
||||
{% method %}
|
||||
set has_location to true if you want to include only nodes that have geo-coordinates set
|
||||
(setting this to false has no sensible effect, unless you'd want to hide nodes that have coordinates)
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
has_location = true
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### [nodes.output.example.filter.in_area]
|
||||
{% method %}
|
||||
nodes outside this area are not shown on the map but are still listed as a node without coordinates
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
latitude_min = 34.30
|
||||
latitude_max = 71.85
|
||||
longitude_min = -24.96
|
||||
longitude_max = 39.72
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [[nodes.output.meshviewer-ffrgb]]
|
||||
{% method %}
|
||||
The new json file format for the [meshviewer](https://github.com/ffrgb/meshviewer) developed in Regensburg.
|
||||
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[[nodes.output.meshviewer-ffrgb]]
|
||||
enable = true
|
||||
path = "/var/www/html/meshviewer/data/meshviewer.json"
|
||||
#[nodes.output.meshviewer-ffrgb.filter]
|
||||
#no_owner = false
|
||||
#blacklist = ["00112233445566", "1337f0badead"]
|
||||
#has_location = true
|
||||
|
||||
#[nodes.output.meshviewer-ffrgb.filter.in_area]
|
||||
#latitude_min = 34.30
|
||||
#latitude_max = 71.85
|
||||
#longitude_min = -24.96
|
||||
#longitude_max = 39.72
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### path
|
||||
{% method %}
|
||||
The path, where to store meshviewer.json
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
path = "/var/www/html/meshviewer/data/meshviewer.json"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [[nodes.output.meshviewer]]
|
||||
{% method %}
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[[nodes.output.meshviewer]]
|
||||
enable = false
|
||||
version = 2
|
||||
nodes_path = "/var/www/html/meshviewer/data/nodes.json"
|
||||
graph_path = "/var/www/html/meshviewer/data/graph.json"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### version
|
||||
{% method %}
|
||||
The structure version of the output which should be generated (i.e. nodes.json)
|
||||
* version 1 is accepted by the legacy meshviewer (which is the master branch)
|
||||
* https://github.com/ffnord/meshviewer/tree/master
|
||||
* version 2 is accepted by the new version of meshviewer (which are in legacy develop branch or newer)
|
||||
* https://github.com/ffnord/meshviewer/tree/dev
|
||||
* https://github.com/ffrgb/meshviewer/tree/develop
|
||||
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
version = 2
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### nodes_path
|
||||
{% method %}
|
||||
The path, where to store nodes.json (supports version 1 and two, see `nodes_version`)
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
nodes_path = "/var/www/html/meshviewer/data/nodes.json"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### graph_path
|
||||
{% method %}
|
||||
The path, where to store graph.json (only version 1)
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
graph_path = "/var/www/html/meshviewer/data/graph.json"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [[nodes.output.nodelist]]
|
||||
{% method %}
|
||||
The nodelist output is a minimal output with current state of collected data.
|
||||
Should be prefered to use it on the [ffapi](https://freifunk.net/api-generator/) for the [freifunk-karte.de](https://freifunk-karte.de)
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[[nodes.output.nodelist]]
|
||||
enable = false
|
||||
path = "/var/www/html/meshviewer/data/nodelist.json"
|
||||
#[nodes.output.nodelist.filter]
|
||||
#no_owner = false
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### path
|
||||
{% method %}
|
||||
The path, where to store nodelist.json
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
path = "/var/www/html/meshviewer/data/nodelist.json"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [database]
|
||||
{% method %}
|
||||
The database organize all database types.
|
||||
For all database types the is a internal job, which reset data for nodes (global statistics are still stored).
|
||||
_(We have for privacy policy to store node data for maximum seven days.)_
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
delete_after = "7d"
|
||||
delete_interval = "1h"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### delete_after
|
||||
{% method %}
|
||||
This will send delete commands to the database to prune data which is older than:
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
delete_after = "7d"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### delete_interval
|
||||
{% method %}
|
||||
How often run the delete commands.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
delete_interval = "1h"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
## [[database.connection.example]]
|
||||
{% method %}
|
||||
This example block shows all option which is useable for every following database type.
|
||||
Every database type has his own configuration under `database.connection`.
|
||||
It is possible to have multiple connections for one type of database, just add this group again with new parameters (see toml [[array of table]]).
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
[[database.connection.example]]
|
||||
enable = true
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### enable
|
||||
{% method %}
|
||||
Each database-connection has its own config block and needs to be enabled by adding:
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = true
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [[database.connection.influxdb]]
|
||||
{% method %}
|
||||
Save collected data to InfluxDB.
|
||||
There are would be the following measurements:
|
||||
- node: store node specific data i.e. clients memory, airtime
|
||||
- global: store global data, i.e. count of clients and nodes
|
||||
- firmware: store the count of nodes tagged with firmware
|
||||
- model: store the count of nodes tagged with hardware model
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = false
|
||||
address = "http://localhost:8086"
|
||||
database = "ffhb"
|
||||
username = ""
|
||||
password = ""
|
||||
[database.connection.influxdb.tags]
|
||||
tagname1 = "tagvalue 1"
|
||||
system = "productive"
|
||||
site = "ffhb"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### address
|
||||
{% method %}
|
||||
Address to connect on InfluxDB server.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
address = "http://localhost:8086"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### database
|
||||
{% method %}
|
||||
Database on which the measurement should be stored.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
database = "ffhb"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### username
|
||||
{% method %}
|
||||
Username to authenticate on InfluxDB
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
username = ""
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### password
|
||||
{% method %}
|
||||
Password to authenticate on InfluxDB.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
password = ""
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### [database.connection.influxdb.tags]
|
||||
{% method %}
|
||||
You could set manuelle tags with inserting into a influxdb.
|
||||
Usefull if you want to identify the yanic instance when you use multiple own on the same influxdb (e.g. multisites).
|
||||
|
||||
Warning:
|
||||
Tags used by Yanic would override the tags from this config (e.g. `nodeid`, `hostname`, `owner`, `model`, `firmware_base`, `firmware_release`, `frequency11g`, `frequency11a`).
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
tagname1 = "tagvalue 1s"
|
||||
# some usefull e.g.:
|
||||
system = "productive"
|
||||
site = "ffhb"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [[database.connection.graphite]]
|
||||
{% method %}
|
||||
Save collected data to a graphite database.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = false
|
||||
address = "localhost:2003"
|
||||
prefix = "freifunk"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### address
|
||||
{% method %}
|
||||
Address to connect on graphite server.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
address = "localhost:2003"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### prefix
|
||||
{% method %}
|
||||
Graphite is replacing every "." in the metric name with a slash "/" and uses
|
||||
that for the file system hierarchy it generates. it is recommended to at least
|
||||
move the metrics out of the root namespace (that would be the empty prefix).
|
||||
If you only intend to run one community and only freifunk on your graphite node
|
||||
then the prefix can be set to anything (including the empty string) since you
|
||||
probably wont care much about "polluting" the namespace.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
prefix = "freifunk"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
|
||||
## [[database.connection.logging]]
|
||||
{% method %}
|
||||
This database type is just for, debugging without a real database connection.
|
||||
A example for other developers for new database types.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
enable = false
|
||||
path = "/var/log/yanic.log"
|
||||
```
|
||||
{% endmethod %}
|
||||
|
||||
|
||||
### path
|
||||
{% method %}
|
||||
Path to file where to store some examples with every line.
|
||||
{% sample lang="toml" %}
|
||||
```toml
|
||||
path = "/var/log/yanic.log"
|
||||
```
|
||||
{% endmethod %}
|
|
@ -0,0 +1,57 @@
|
|||
# Build and Installation
|
||||
|
||||
## go
|
||||
|
||||
### Install
|
||||
```sh
|
||||
cd /usr/local/
|
||||
wget https://storage.googleapis.com/golang/go1.9.1.linux-amd64.tar.gz -O go-release-linux-amd64.tar.gz
|
||||
tar xvf go-release-linux-amd64.tar.gz
|
||||
rm go-release-linux-amd64.tar.gz
|
||||
```
|
||||
|
||||
### Configure go
|
||||
Add these lines in your root shell startup file (e.g. `/root/.bashrc`):
|
||||
|
||||
```sh
|
||||
export GOPATH=/opt/go
|
||||
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
|
||||
```
|
||||
|
||||
## Yanic
|
||||
|
||||
### Compile
|
||||
As root:
|
||||
```sh
|
||||
go get -v -u github.com/FreifunkBremen/yanic
|
||||
```
|
||||
|
||||
### Install
|
||||
|
||||
```sh
|
||||
cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/yanic.service
|
||||
systemctl daemon-reload
|
||||
```
|
||||
|
||||
Before start, you should configurate yanic by the file `/etc/yanic.conf`:
|
||||
|
||||
```
|
||||
systemctl start yanic
|
||||
```
|
||||
|
||||
Enable to start on boot:
|
||||
|
||||
```
|
||||
systemctl enable yanic
|
||||
```
|
||||
|
||||
### Update
|
||||
For an update just stop yanic and then call the same `go` command again (again as root):
|
||||
```sh
|
||||
systemctl stop yanic
|
||||
go get -v -u github.com/FreifunkBremen/yanic
|
||||
```
|
||||
Then update the config file, for example look at the diff with the new example:
|
||||
```sh
|
||||
diff /opt/go/src/github.com/FreifunkBremen/yanic/config_example.toml /etc/yanic.conf
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
# Quick Configuration
|
||||
|
||||
```sh
|
||||
cp /opt/go/src/github.com/FreifunkBremen/yanic/config_example.toml /etc/yanic.conf
|
||||
```
|
||||
|
||||
# Quick configuration
|
||||
For an easy startup you only need to edit the `interfaces` in section
|
||||
`[respondd]` in file `/etc/yanic.conf`.
|
||||
|
||||
Then create the following files and folders:
|
||||
```sh
|
||||
adduser --system yanic --home /var/lib/yanic
|
||||
mkdir -p /var/lib/yanic
|
||||
mkdir -p /var/www/html/meshviewer/data
|
||||
touch /var/log/yanic.log
|
||||
chown yanic /var/log/yanic.log /var/lib/yanic /var/www/html/meshviewer/data
|
||||
```
|
||||
|
||||
#### Standalone
|
||||
If you like to run a standalone meshviewer, just set `enable` in section
|
||||
`[webserver]` to `true`.
|
||||
|
||||
##### Configure the [meshviewer](https://github.com/ffrgb/meshviewer):
|
||||
set `dataPath` in `config.json` to `/data/` and make the `build` directory
|
||||
accessible under `/var/www/html/meshviewer`.
|
||||
|
||||
#### With webserver (Apache, nginx)
|
||||
The meshviewer needs the output files like `nodes_path` and `graph_path` inside
|
||||
the same directory as the `dataPath`. Change the path in the section
|
||||
`[meshviewer]` accordingly.
|
|
@ -0,0 +1,75 @@
|
|||
# Usage
|
||||
|
||||
Yanic provides several commands:
|
||||
|
||||
* `import`
|
||||
* `query`
|
||||
* `serve`
|
||||
|
||||
## Import
|
||||
|
||||
### RRD-File
|
||||
Warning, just tested with olddata.rrd from Freifunk Bremen generated by detailed-rrds branch of [ffmap-backend](https://github.com/ffnord/ffmap-backend/tree/detailed-rrds)
|
||||
|
||||
```
|
||||
Usage:
|
||||
yanic import <file.rrd> [flags]
|
||||
|
||||
Examples:
|
||||
yanic import --config /etc/yanic.toml olddata.rrd
|
||||
|
||||
Flags:
|
||||
-c, --config string Path to configuration file (default "config.toml")
|
||||
-h, --help help for import
|
||||
```
|
||||
|
||||
### Firstseen
|
||||
To import firstseen values there is a little script in contrib:
|
||||
|
||||
```
|
||||
/opt/go/src/github.com/FreifunkBremen/yanic/contrib/yanic-import-timestamp -n path/to/nodes_old.json -s state.json /var/lib/yanic/state.json
|
||||
```
|
||||
|
||||
On a productive system @ once:
|
||||
|
||||
```
|
||||
systemctl stop yanic; cp /var/lib/yanic/state.json /var/lib/yanic/state.bak; /opt/go/src/github.com/FreifunkBremen/yanic/contrib/yanic-import-timestamp -n path/to/nodes_old.json -s /var/lib/yanic/state.json; systemctl start yanic;
|
||||
```
|
||||
|
||||
## Serve
|
||||
runs yanic in collector-modus to genereate files (e.g. for meshviewer) and save values in databases
|
||||
|
||||
from shell
|
||||
|
||||
```
|
||||
Usage:
|
||||
yanic serve [flags]
|
||||
|
||||
Examples:
|
||||
yanic serve --config /etc/yanic.toml
|
||||
|
||||
Flags:
|
||||
-c, --config string Path to configuration file (default "config.toml")
|
||||
-h, --help help for serve
|
||||
```
|
||||
|
||||
or run as [daemon]({{site.baseurl}}/docs/install.html)
|
||||
|
||||
|
||||
## Query
|
||||
|
||||
Send a single request and show response like `gluon-neighbour-info` on gluon.
|
||||
|
||||
e.g. to check the right interface
|
||||
|
||||
```
|
||||
Usage:
|
||||
yanic query <interface> <destination> [flags]
|
||||
|
||||
Examples:
|
||||
yanic query wlan0 "fe80::eade:27ff:dead:beef"
|
||||
|
||||
Flags:
|
||||
-h, --help help for query
|
||||
--wait int Seconds to wait for a response (default 1)
|
||||
```
|
|
@ -0,0 +1,45 @@
|
|||
# About
|
||||
|
||||
A little overview of yanic in connection with other software:
|
||||
![Overview](overview.svg)
|
||||
|
||||
## How respondd works
|
||||
|
||||
It sends the `gluon-neighbour-info` request and collects the answers.
|
||||
|
||||
It will send UDP packets with multicast group `ff02:0:0:0:0:0:2:1001` and port `1001`.
|
||||
|
||||
If a node does not answer, it will request with the last know address under the port `1001`.
|
||||
|
||||
## Related projects
|
||||
|
||||
#### yanic collecting data
|
||||
VPNs (respondd for servers):
|
||||
|
||||
* [mesh-announce](https://github.com/ffnord/mesh-announce) from FreiFunkNord
|
||||
* [respondd](https://github.com/Sunz3r/ext-respondd) from Sunz3r
|
||||
|
||||
Nodes (respondd for nodes): [gluon](https://github.com/freifunk-gluon/gluon/)
|
||||
|
||||
#### Alternative collectors of respondd data:
|
||||
|
||||
* [Node informant](https://github.com/ffdo/node-informant) written in Go
|
||||
* [HopGlass Server](https://github.com/plumpudding/hopglass-server) written in Node.js
|
||||
|
||||
#### yanic published data
|
||||
|
||||
**Databases:**
|
||||
|
||||
* [InfluxDB](https://influxdata.com/) SQL-like timeserial database
|
||||
* [Graphite](https://graphiteapp.org/) RRD file Based
|
||||
|
||||
Visualization from Databases: [Grafana](https://grafana.com/)
|
||||
|
||||
**Output:**
|
||||
* meshviewer-ffrgb:
|
||||
* [meshviewer](https://github.com/ffrgb/meshviewer)
|
||||
* nodelist:
|
||||
* [ffapi](https://freifunk.net/api-generator/)
|
||||
* [freifunk-karte.de](https://freifunk-karte.de)
|
||||
* meshviewer (others):
|
||||
* unmaintained [origin meshviewer](https://github.com/ffnord/meshviewer) branch: master (v1) and dev (v2)
|
|
@ -0,0 +1,24 @@
|
|||
# Running Yanic
|
||||
|
||||
| Community | Meshviewer | Database Visualisation \(Grafana\) |
|
||||
| :--- | :--- | :--- |
|
||||
| Freifunk Bremen | [meshviewer](https://map.bremen.freifunk.net) from Freifunk Regensburgwith a patch to show state.json | [grafana](https://grafana.bremen.freifunk.net) - with influxdb |
|
||||
| Freifunk Regensburg | [meshviewer ](https://regensburg.freifunk.net/meshviewer/)from Freifunk Regensburg | [grafana](https://grafana.regensburg.freifunk.net/) - without yanic |
|
||||
| Freifunk Frankfurt am Main | [meshviewer ](https://map.ffm.freifunk.net)from Freifunk Regensburg | - |
|
||||
| Freifunk Hannover | [meshviewer ](https://hannover.freifunk.net/karte/)from Freifunk Regensburg | [grafana ](https://stats.ffh.zone)with influxdb |
|
||||
| Freifunk Hochstift | [meshviewer ](https://map.hochstift.freifunk.net)from Freifunk Regensburg | - |
|
||||
| Freifunk in Mainz , Wiesbaden & Umgebung | [meshviewer ](https://mapng.freifunk-mwu.de/)from Freifunk Regensburg | [grafana](https://stats.freifunk-mwu.de) with influxdb |
|
||||
| Freifunk Ulzen | [meshviewer ](http://map.ffue.eu)from Freifunk Regensburg | - |
|
||||
| Freifunk Gera Greiz | [meshviewer](https://www.freifunk-gera-greiz.de/meshviewer/) from Freifunk Regensburg | [grafana](https://www.freifunk-gera-greiz.de/grafana/dashboard/db/meshviewer-graphen) - with influxdb |
|
||||
| Freifunk Westpfalz | [meshviewer ](https://map.freifunk-westpfalz.de/)from Freifunk Regensburg | [grafana](https://stats.freifunk-westpfalz.de/)- with influxdb |
|
||||
|
||||
|
||||
### meshviewer-collector
|
||||
A little project starts, to collect meshviewer-ffrgb data from multiple communities.
|
||||
|
||||
|
||||
List of communities:
|
||||
[https://github.com/genofire/meshviewer-collector](https://github.com/genofire/meshviewer-collector/blob/master/config.toml)
|
||||
|
||||
Meshviewer with colleced data:
|
||||
[https://web.fireorbit.de/meshviewer](https://web.fireorbit.de/meshviewer).
|
|
@ -0,0 +1,24 @@
|
|||
# Home
|
||||
|
||||
|
||||
__ __ _
|
||||
\ \ / /_ _ _ __ (_) ___
|
||||
\ V / _` | '_ \| |/ __|
|
||||
| | (_| | | | | | (__
|
||||
|_|\__,_|_| |_|_|\___|
|
||||
Yet another node info collector
|
||||
|
||||
(previously [respond-collector](https://github.com/FreifunkBremen/respond-collector))
|
||||
|
||||
[![Build Status](https://travis-ci.org/FreifunkBremen/yanic.svg?branch=master)](https://travis-ci.org/FreifunkBremen/yanic)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/FreifunkBremen/yanic/badge.svg?branch=master)](https://coveralls.io/github/FreifunkBremen/yanic?branch=master)
|
||||
[![codecov](https://codecov.io/gh/FreifunkBremen/yanic/branch/master/graph/badge.svg)](https://codecov.io/gh/FreifunkBremen/yanic)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/FreifunkBremen/yanic)](https://goreportcard.com/report/github.com/FreifunkBremen/yanic)
|
||||
|
||||
`yanic` is a respondd client that fetches, stores and publishes information about a Freifunk network.
|
||||
|
||||
## The goals:
|
||||
|
||||
* Generating JSON for [Meshviewer](https://github.com/ffrgb/meshviewer)
|
||||
* Storing statistics in [InfluxDB](https://influxdata.com/) or [Graphite](https://graphiteapp.org/) to be analyzed by [Grafana](http://grafana.org/)
|
||||
* Provide a little webserver for a standalone installation with a meshviewer
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1 @@
|
|||
<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0" version="7.6.7" editor="www.draw.io" type="device"><diagram id="c22c9a54-a830-b601-ab41-3f056e49af3e" name="Page-1">5Vptc6M2EP41nsl9sAchwM7HOG/tTO96M2nvmo+yEaAEI1eI2L5fXwkk8yLsOrHB7jUfYlgtQuw+z+5qYQBvF+tHhpbRZ+rjeGBb/noA7wa2DSxnIn6kZFNIPGgVgpARXymVgifyA+srlTQjPk5ripzSmJNlXTinSYLnvCZDjNFVXS2gcf2uSxRiQ/A0R7Ep/U58HhXSiWuV8l8wCSN9Z2CpkRmav4aMZom638CGQf5XDC+QnkvppxHy6aoigvcDeMso5cXRYn2LY2lbbbbiuocdo9t1M5zwQy6AUK2Db/SzY1+YQp1SxiMa0gTF96V0mj8fljNY4izii1gcAnGI14T/JcUjV509q5EXzPlG+RllnApROfdvlC6VXrEauYSdD6REKc3YXGnZW8sJRGK6wJxthArDMeLkrT4VUtAIt3rbS79SIm5iWwrGUKNRgdj2rPoUHLEQc3VVaWRxUFlGKcpN3+4Gu5j4DcWZWu0XKglge7F46umMiaNQHl1pERLqEcNBru39nUnACFdwSZAbuRT7ISQ8ymajOV2Ik4BhEmTJ6zCMM5rIUfVbXq3voUaK+wgNpAc+GVhZRYTjpyXKHbESsaCOB5QuC3YGZC3xotz7hhnH6/0ONr2pvTKue0VzclXyFGhHRVWONr1XBUDNdfv8BAwTdEIXYQu2qQzJ02c1QbdUUvGggLay8JHsOtS40CDBt69fTsqBIKHMl8vAaTRESSIcI567jQMNjQvlwjbtnIMLOjpW/HWHOJqhFHdDErvfpOKaTPB6YoLdUVYeX06cabEuGPdlXud/ad5JT+Z1rJ7Me6gJ97nhdOa97qYIdesh3gGT+hTFsowi1Jho3KhmnQmsT7Sjmr1hDG0qakupkL5jwe7kfeuq64uDYgUHltZ/ppj9PnuRqda2YjTD8UBtxD5WMzyounnK8ALLenmDEjI3C4ZnJTYKheLhNDeqtZSizXlLCBvu2OR0UUOI04p/dpQVPe1IzxebPTN49JX5vN0lm0R/s9IeDmT74GDi+HSejkgSxNnaF9MqBinBrLXO/nU72MacI9cTyuaUYNSIYSTAjIv10daFfI+IYJe408Ojumo3mc+8AW7G8T6LfqeTDTCocLOg4/tTe43D+RwfY+e4JbUfuwP+UCLdslU5euw1Wnn/qg+OSaSm680mFVnIPmoTEALavO5nhlPyA81yBeko9ehC250O3DtJlJiEiRDMhWsEC+FUUoTMUXyjBhbE93Mw5Tl9um2z3tKYsvy+utG6h2SqXaxWMth2YauQcPazzxoBYKkS7KOlnVahQZDiY1uHY8Mr74uQAUp0pDaj4mMxflh0vvpG0kw4MiWc0OQiGiSNWOlNQI+xErhHuabeuWLhTDWu3gheyUTV9NXn6thFZi7bhWd0hw6P/+1XHaCL/HQwos1gUyJyqEBqhIVSZfSSXkhgsMeTehV17ZpQBG1QBCeAIuwJiufb4+guRRWmlRecHb9IMGEaBGhJfrJKBe5oR5eVCmygHFxQ3aIRUnFSIr8jICnPw8QlRAnHc88ZJeyfPkpcm1EC7nDJ6ZPZ9Z5kJuRXb6BoN6CFhFrxX+rbn8wkJ6GbKtyKa6Re3n24GCh7TgPKkxYowzYow1PUXua7wneUwttvF16RsMDIx2bx26ZykTWw4zS3JL1+v2AGXZHxljTx/QOSY8oZfcU6jyU0kQEnIHHcEB2eItscUI9gJzC5fd1ocQPT5E6Lxe1TGNwMMjTjy4yfphYRETktgjOo2D3GAW+xOpfRepoKa5Mk/CMP3UPnRKi26zs7B04ME7sdmRgC08Q8wiw9mu4+SqMciOBEMdhoR3T7rqX8jLCoz8pvNeH9Pw==</diagram></mxfile>
|
|
@ -32,7 +32,6 @@ func TestStart(t *testing.T) {
|
|||
conn := &testConn{}
|
||||
config := &runtime.Config{
|
||||
Nodes: struct {
|
||||
Enable bool `toml:"enable"`
|
||||
StatePath string `toml:"state_path"`
|
||||
SaveInterval runtime.Duration `toml:"save_interval"`
|
||||
OfflineAfter runtime.Duration `toml:"offline_after"`
|
||||
|
|
|
@ -22,7 +22,6 @@ type Config struct {
|
|||
Webroot string `toml:"webroot"`
|
||||
}
|
||||
Nodes struct {
|
||||
Enable bool `toml:"enable"`
|
||||
StatePath string `toml:"state_path"`
|
||||
SaveInterval Duration `toml:"save_interval"` // Save nodes periodically
|
||||
OfflineAfter Duration `toml:"offline_after"` // Set node to offline if not seen within this period
|
||||
|
|
Loading…
Reference in New Issue