Skip to content

Commit

Permalink
Merge pull request #9 from MacroPower/collector-v2
Browse files Browse the repository at this point in the history
Use collector model from node_exporter
  • Loading branch information
MacroPower authored Sep 25, 2020
2 parents f807de0 + b001f99 commit 7eeba5d
Show file tree
Hide file tree
Showing 53 changed files with 1,637 additions and 1,363 deletions.
540 changes: 201 additions & 339 deletions LICENSE

Large diffs are not rendered by default.

72 changes: 55 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<a href="#"><img src="img/waka_header.png"></a>

<h2></h2>
<p align="center">
<a href="#" target="blank">
Expand All @@ -18,7 +19,12 @@
</a>
</p>

_wakatime_exporter_ is a Prometheus exporter for Wakatime statistics. It intends to extend the existing Wakatime ecosystem via allowing users to make use of Prometheus (and therefore any consumers of its API) as companion services alongside the traditional Wakatime web application. This could be anything from including some of your coding statistics in Grafana, to forecasting your coding time with prophet. Sky's the limit!
_wakatime_exporter_ is a Prometheus exporter for [Wakatime](https://wakatime.com/) statistics.
It intends to extend the existing Wakatime ecosystem
via allowing users to make use of Prometheus (and therefore any consumers of its API)
as companion services alongside the traditional Wakatime web application.
This could be anything from including some of your coding statistics in Grafana,
to forecasting your coding time with prophet.

> NOTE: _wakatime_exporter_ is currently in ALPHA. Expect things to break and change.
Expand All @@ -31,7 +37,8 @@ _wakatime_exporter_ is a Prometheus exporter for Wakatime statistics. It intends
## Usage

In most cases, you should only need to provide an API key.
All other parameters are for advanced use-cases only and you should be able to leave them set to their defaults.
All other parameters are for advanced use-cases only
and you should be able to leave them set to their defaults.

You can get your Wakatime API key by visiting: https://wakatime.com/api-key

Expand All @@ -41,36 +48,67 @@ Provide arguments via parameters:
usage: wakatime_exporter --wakatime.api-key=WAKATIME.API-KEY [<flags>]
Flags:
--help Show context-sensitive help.
--web.listen-address=":9212" Address to listen on for web interface and telemetry.
--web.telemetry-path="/metrics" Path under which to expose metrics.
--help, -h Show context-sensitive help.
--collector.all-time Enable the all-time collector (default: enabled).
--collector.goal Enable the goal collector (default: enabled).
--collector.leader Enable the leader collector (default: enabled).
--collector.summary Enable the summary collector (default: enabled).
--collector.disable-defaults Set all collectors to disabled by default.
--web.listen-address=":9212" Address to listen on for web interface and telemetry.
--web.metrics-path="/metrics" Path under which to expose metrics.
--web.disable-exporter-metrics Exclude metrics about the exporter itself (promhttp_*, process_*, go_*).
--wakatime.scrape-uri="https://wakatime.com/api/v1"
Base path to query for Wakatime data.
--wakatime.user="current" User to query for Wakatime data.
--wakatime.api-key=WAKATIME.API-KEY Token to use when getting stats from Wakatime.
--wakatime.timeout=5s Timeout for trying to get stats from Wakatime.
--wakatime.ssl-verify Flag that enables SSL certificate verification.
--log.level=info Only log messages with the given severity or above.
One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages.
One of: [logfmt, json]
--version Show application version.
Base path to query for Wakatime data.
--wakatime.user="current" User to query for Wakatime data.
--wakatime.api-key Token to use when getting stats from Wakatime.
--wakatime.timeout=5s Timeout for trying to get stats from Wakatime.
--wakatime.ssl-verify Flag that enables SSL certificate verification for the scrape URI.
--log.level=info Only log messages with the given severity or above.
One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages.
One of: [logfmt, json]
--version Show application version.
```

and/or via environment variables:

```
WAKA_LISTEN_ADDR=":9212" # Address to listen on for web interface and telemetry.
```shell
WAKA_LISTEN_ADDRESS=":9212" # Address to listen on for web interface and telemetry.
WAKA_METRICS_PATH="/metrics" # Path under which to expose metrics.
WAKA_SCRAPE_URI="https://wakatime.com/api/v1" # Base path to query for Wakatime data.
WAKA_USER="current" # User to query for Wakatime data.
WAKA_API_KEY="" # Token to use when getting stats from Wakatime.
WAKA_TIMEOUT="5s" # Timeout for trying to get stats from Wakatime.
WAKA_SSL_VERIFY="true" # SSL certificate verification for the scrape URI.
WAKA_DISABLE_EXPORTER_METRICS="false" # Exclude metrics about the exporter itself.
WAKA_COLLECTOR_ALLTIME="true" # Enable the all-time collector.
WAKA_COLLECTOR_GOAL="true" # Enable the goal collector.
WAKA_COLLECTOR_LEADER="true" # Enable the leader collector.
WAKA_COLLECTOR_SUMMARY="true" # Enable the summary collector.
```

## Docker

```shell
docker run -p 9212:9212 macropower/wakatime-exporter:latest --wakatime.api-key="YOUR_API_KEY"
```

## Compatibility

_wakatime_exporter_ is designed to work with [Wakatime](https://wakatime.com/).
However, you can additionally use any other application
that is compliant with the [Wakatime API](https://wakatime.com/developers),
e.g. [wakapi](https://github.com/muety/wakapi),
via `--wakatime.scrape-uri` or `WAKA_SCRAPE_URI`.
If said application only implements portions of the Wakatime API,
you can disable collectors for any non-compliant or non-existent endpoints
using parameters or environment variables as described in [usage](#usage).

## License

This project was licensed GPL-2.0 from 0.0.0 to 0.0.5.

As of 0.0.6, parts of this application use code from node_exporter, which is licensed APACHE 2.0.

As of 0.0.6, this project in its entirety, excluding any packages found in vendor, is licensed APACHE 2.0.
Each file in this project has a license header which identifies the copyright for said file.
90 changes: 90 additions & 0 deletions collector/all-time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
Copyright 2020 Jacob Colvin (MacroPower)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package collector

import (
"errors"
"io"
"net/url"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/prometheus/client_golang/prometheus"
)

const (
allTimeCollector = "all-time"
allTimeSubsystem = "cumulative"
allTimeEndpoint = "all_time_since_today"
)

type alltimeCollector struct {
total *prometheus.Desc
uri url.URL
fetchStat func(url.URL, string, url.Values) (io.ReadCloser, error)
logger log.Logger
}

func init() {
registerCollector(allTimeCollector, defaultEnabled, NewAllTimeCollector)
}

// NewAllTimeCollector returns a new Collector exposing all-time stats.
func NewAllTimeCollector(in CommonInputs, logger log.Logger) (Collector, error) {
return &alltimeCollector{
total: prometheus.NewDesc(
prometheus.BuildFQName(namespace, allTimeSubsystem, "seconds_total"),
"Total seconds (all time).",
nil, nil,
),
uri: in.URI,
fetchStat: FetchHTTP(in.Token, in.SSLVerify, in.Timeout, logger),
logger: logger,
}, nil
}

func (c *alltimeCollector) Update(ch chan<- prometheus.Metric) error {
params := url.Values{}
params.Add("cache", "false")

body, fetchErr := c.fetchStat(c.uri, allTimeEndpoint, params)
if fetchErr != nil {
return fetchErr
}

alltimeStats := wakatimeAlltime{}
if err := ReadAndUnmarshal(body, &alltimeStats); err != nil {
return err
}

defer body.Close()

level.Info(c.logger).Log(
"msg", "Collecting all-time from Wakatime",
"IsUpToDate", alltimeStats.Data.IsUpToDate,
)
if alltimeStats.Data.IsUpToDate == true {
ch <- prometheus.MustNewConstMetric(
c.total,
prometheus.CounterValue,
alltimeStats.Data.TotalSeconds,
)
} else {
return errors.New("skipped scrape of all-time metrics because they were not up to date")
}

return nil
}
24 changes: 24 additions & 0 deletions collector/all-time_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Copyright 2020 Jacob Colvin (MacroPower)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package collector

type wakatimeAlltime struct {
Data struct {
IsUpToDate bool `json:"is_up_to_date"`
Text string `json:"text"`
TotalSeconds float64 `json:"total_seconds"`
} `json:"data"`
}
Loading

0 comments on commit 7eeba5d

Please sign in to comment.