diff --git a/README.md b/README.md index 2b4d035..d311d1f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,82 @@ # freebox-exporter -Prometheus exporter for the Freebox + +Prometheus exporter for the [Freebox](https://www.free.fr/freebox/) + +**Disclaimer**: I am not related to Iliad, Free or any of their subsidiaries. I have only created this Prometheus exporter to monitor my own device using some [publicly available documentation](https://dev.freebox.fr/sdk/os/). + +## Install + +Having a working Golang environment using Go modules: + +```bash +go install github.com/trazfr/freebox-exporter@latest +``` + +## Use + +This program is to be run in 2 steps, as you must authorize the exporter to access the Freebox. Once authorized, it may be run from anywhere. + +``` +Usage: freebox-exporter [options] + +api_token_file: file to store the token for the API + +options: + -debug + enable the debug mode + -hostDetails + get details about the hosts connected to wifi and ethernet. This increases the number of metrics + -httpDiscovery + use http://mafreebox.freebox.fr/api_version to discover the Freebox at the first run (by default: use mDNS) + -listen string + listen to address (default ":9091") +``` + +### Step 1 authorize API + +From the Freebox network, generate a token file for the API. The file `token.json` must not exist: + +```bash +$ freebox-exporter token.json +Could not find the configuration file token.json +Freebox discovery: mDNS +1 Please accept the login on the Freebox Server +... +``` + +You must accept the API on the Freebox device. + +Once done, the credentials will be stored in the new file `token.json` + +**In case of errors**: + +If you get the message `panic: Access is timeout`, you have to be faster to accept the access on the Freebox. + +If you get the message `panic: MDNS timeout`, there may be a firewall preventing you to use mDNS. You may try to get the token using HTTP: + +```bash +$ freebox-exporter -httpDiscovery token.json +Could not find the configuration file token.json +Freebox discovery: GET http://mafreebox.freebox.fr/api_version +1 Please accept the login on the Freebox Server +... +``` + +### Step 2 run + +Once you have generated the token you may run from anywhere. + +```bash +$ freebox-exporter token.json +Use configuration file token.json +Listen to :9091 +``` + +Then you may test it: + +```bash +$ curl 127.0.0.1:9091/metrics +# HELP freebox_connection_bandwith_bps available upload/download bandwidth in bit/s +# TYPE freebox_connection_bandwith_bps gauge +... +``` \ No newline at end of file diff --git a/fbx/api_version.go b/fbx/api_version.go index 97a688f..b2d4490 100644 --- a/fbx/api_version.go +++ b/fbx/api_version.go @@ -46,7 +46,7 @@ func NewFreeboxAPIVersion(client *FreeboxHttpClient, discovery FreeboxDiscovery) if result.IsValid() == false { return nil, errors.New("Could not get the API version") } - log.Info.Println("APIVersion", result) + log.Debug.Println("APIVersion", result) return result, nil } diff --git a/log/log.go b/log/log.go index 60f02d6..d0674e0 100644 --- a/log/log.go +++ b/log/log.go @@ -1,8 +1,9 @@ package log import ( - "io" + "io/ioutil" "log" + "os" ) var ( @@ -12,25 +13,27 @@ var ( Error *log.Logger ) -func Init( - debugHandle io.Writer, - infoHandle io.Writer, - warningHandle io.Writer, - errorHandle io.Writer) { - - Debug = log.New(debugHandle, +func InitDebug() { + Debug = log.New(os.Stdout, "DEBUG: ", log.Ldate|log.Ltime|log.Lshortfile) - Info = log.New(infoHandle, + Info = log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) - Warning = log.New(warningHandle, + Warning = log.New(os.Stdout, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile) - Error = log.New(errorHandle, + Error = log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) } + +func Init() { + Debug = log.New(ioutil.Discard, "", 0) + Info = log.New(os.Stdout, "", 0) + Warning = log.New(os.Stdout, "", 0) + Error = log.New(os.Stderr, "", 0) +} diff --git a/main.go b/main.go index c7035b0..028f199 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,8 @@ package main import ( - "errors" "flag" "fmt" - "io/ioutil" "net/http" "os" @@ -15,34 +13,39 @@ import ( "github.com/trazfr/freebox-exporter/log" ) -func usage(err error) { - if err != nil { - fmt.Fprintln(os.Stderr, "Error:", err) - } - fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "[options] ") - fmt.Fprintln(os.Stderr) - fmt.Fprintln(os.Stderr, "Options:") +func usage() { + fmt.Fprintf(flag.CommandLine.Output(), + "Usage: %s [options] \n"+ + "\n"+ + "api_token_file: file to store the token for the API\n"+ + "\n"+ + "options:\n", + os.Args[0]) flag.PrintDefaults() - os.Exit(-1) } func main() { + flag.Usage = usage debugPtr := flag.Bool("debug", false, "enable the debug mode") hostDetailsPtr := flag.Bool("hostDetails", false, "get details about the hosts connected to wifi and ethernet. This increases the number of metrics") - httpDiscoveryPtr := flag.Bool("httpDiscovery", false, "use http://mafreebox.freebox.fr/api_version to discover the Freebox at the first run (default: mDNS)") + httpDiscoveryPtr := flag.Bool("httpDiscovery", false, "use http://mafreebox.freebox.fr/api_version to discover the Freebox at the first run (by default: use mDNS)") listenPtr := flag.String("listen", ":9091", "listen to address") flag.Parse() args := flag.Args() if len(args) < 1 { - usage(errors.New("api_token_file not defined")) + fmt.Fprintf(flag.CommandLine.Output(), "ERROR: api_token_file not defined\n") + usage() + os.Exit(1) } else if len(args) > 1 { - usage(errors.New("too many arguments")) + fmt.Fprintf(flag.CommandLine.Output(), "ERROR: too many arguments\n") + usage() + os.Exit(1) } if *debugPtr { - log.Init(os.Stdout, os.Stdout, os.Stdout, os.Stderr) + log.InitDebug() } else { - log.Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr) + log.Init() } discovery := fbx.FreeboxDiscoveryMDNS if *httpDiscoveryPtr { @@ -55,5 +58,6 @@ func main() { prometheus.MustRegister(collector) http.Handle("/metrics", promhttp.Handler()) + log.Info.Println("Listen to", *listenPtr) log.Error.Println(http.ListenAndServe(*listenPtr, nil)) }