feat: add goreport notation

This commit is contained in:
Adrien Waksberg 2019-08-22 22:44:50 +02:00
parent 4bf2f1e02f
commit 0ad5151d98
5 changed files with 186 additions and 181 deletions

View file

@ -7,6 +7,10 @@ Which is based on [Keep A Changelog](http://keepachangelog.com/)
## Unreleased ## Unreleased
### Added
- goreport notation
### Fixed ### Fixed
- too many open files close with influxdb connection - too many open files close with influxdb connection

View file

@ -1,6 +1,7 @@
# Weather # Weather
[![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/weather/releases) [![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/weather/releases)
[![GoReport](https://goreportcard.com/badge/git.yaegashi.fr/nishiki/weather)](https://goreportcard.com/report/git.yaegashi.fr/nishiki/weather)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/weather/src/branch/master/LICENSE) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/weather/src/branch/master/LICENSE)
weather is a small program that fetch weather informations, and store them to influxdb weather is a small program that fetch weather informations, and store them to influxdb

View file

@ -17,78 +17,78 @@
package main package main
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
yaml "gopkg.in/yaml.v2" yaml "gopkg.in/yaml.v2"
) )
// Config struct contains all options // Config struct contains all options
type Config struct { type Config struct {
InfluxDB struct { InfluxDB struct {
URL string `yaml:"url"` URL string `yaml:"url"`
Database string `yaml:"database"` Database string `yaml:"database"`
Measurement string `yaml:"measurement"` Measurement string `yaml:"measurement"`
Username string `yaml:"username"` Username string `yaml:"username"`
Password string `yaml:"password"` Password string `yaml:"password"`
} `yaml:"influxdb"` } `yaml:"influxdb"`
OpenWeatherMap struct { OpenWeatherMap struct {
APIKey string `yaml:"api_key"` APIKey string `yaml:"api_key"`
Units string `yaml:"units"` Units string `yaml:"units"`
} `yaml:"openweathermap"` } `yaml:"openweathermap"`
Cities []string `yaml:"cities"` Cities []string `yaml:"cities"`
Interval int64 `yaml:"interval"` Interval int64 `yaml:"interval"`
} }
// Load the config from a file // Load the config from a file
func (c *Config) Load(path string) error { func (c *Config) Load(path string) error {
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
return err return err
} }
err = yaml.Unmarshal(data, &c) err = yaml.Unmarshal(data, &c)
if err != nil { if err != nil {
return err return err
} }
c.Defaults() c.Defaults()
err = c.Check() err = c.Check()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// Defaults set options with default value // Defaults set options with default value
func (c *Config) Defaults() { func (c *Config) Defaults() {
if c.OpenWeatherMap.Units == "" { if c.OpenWeatherMap.Units == "" {
c.OpenWeatherMap.Units = "metric" c.OpenWeatherMap.Units = "metric"
} }
if c.Interval == 0 { if c.Interval == 0 {
c.Interval = 600 c.Interval = 600
} }
if c.InfluxDB.URL == "" { if c.InfluxDB.URL == "" {
c.InfluxDB.URL = "http://127.0.0.1:8086" c.InfluxDB.URL = "http://127.0.0.1:8086"
} }
if c.InfluxDB.Measurement == "" { if c.InfluxDB.Measurement == "" {
c.InfluxDB.Measurement = "weather" c.InfluxDB.Measurement = "weather"
} }
} }
// Check if the options are good // Check if the options are good
func (c *Config) Check() error { func (c *Config) Check() error {
if c.InfluxDB.Database == "" { if c.InfluxDB.Database == "" {
return fmt.Errorf("you must specify influxdb.database in config file") return fmt.Errorf("you must specify influxdb.database in config file")
} }
if c.OpenWeatherMap.APIKey == "" { if c.OpenWeatherMap.APIKey == "" {
return fmt.Errorf("you must specify api_key in config file") return fmt.Errorf("you must specify api_key in config file")
} }
return nil return nil
} }

84
main.go
View file

@ -17,63 +17,63 @@
package main package main
import ( import (
"fmt" "flag"
"flag" "fmt"
"os" "os"
"time" "time"
) )
// Options and OpenWeatherMap URI // Options and OpenWeatherMap URI
var ( var (
URI = "https://api.openweathermap.org/data/2.5" URI = "https://api.openweathermap.org/data/2.5"
CONFIG = flag.String("config", "", "config file path") CONFIG = flag.String("config", "", "config file path")
DAEMON = flag.Bool("daemon", false, "run in daemon mode") DAEMON = flag.Bool("daemon", false, "run in daemon mode")
HELP = flag.Bool("help", false, "print this help message") HELP = flag.Bool("help", false, "print this help message")
) )
func init() { func init() {
flag.Parse() flag.Parse()
} }
func main() { func main() {
var w Weather var w Weather
if *HELP { if *HELP {
flag.PrintDefaults() flag.PrintDefaults()
os.Exit(1) os.Exit(1)
} }
if *CONFIG == "" { if *CONFIG == "" {
fmt.Println("you must specify a config file with -config option") fmt.Println("you must specify a config file with -config option")
os.Exit(1) os.Exit(1)
} }
err := w.Config.Load(*CONFIG) err := w.Config.Load(*CONFIG)
if err != nil { if err != nil {
fmt.Printf("%s\n", err) fmt.Printf("%s\n", err)
os.Exit(2) os.Exit(2)
} }
for { for {
startTime := time.Now().Unix() startTime := time.Now().Unix()
w.FetchData() w.FetchData()
err = w.SendToInfluxDB() err = w.SendToInfluxDB()
if err != nil { if err != nil {
fmt.Printf("%s\n", err) fmt.Printf("%s\n", err)
} }
if *DAEMON == false { if *DAEMON == false {
if err == nil { if err == nil {
os.Exit(0) os.Exit(0)
} else { } else {
os.Exit(2) os.Exit(2)
} }
} }
sleepTime := time.Now().Unix() - startTime + w.Config.Interval sleepTime := time.Now().Unix() - startTime + w.Config.Interval
if sleepTime > 0 { if sleepTime > 0 {
time.Sleep(time.Duration(sleepTime) * time.Second) time.Sleep(time.Duration(sleepTime) * time.Second)
} }
} }
} }

View file

@ -17,118 +17,118 @@
package main package main
import ( import (
"fmt" "encoding/json"
"net/http" "fmt"
"encoding/json" "io/ioutil"
"io/ioutil" "net/http"
"time" "time"
influx "github.com/influxdata/influxdb1-client/v2" influx "github.com/influxdata/influxdb1-client/v2"
) )
// Weather is the main struct // Weather is the main struct
type Weather struct { type Weather struct {
Config Config Config Config
WeatherDatas []WeatherData WeatherDatas []WeatherData
} }
// WeatherData contains weather data from openweathermap // WeatherData contains weather data from openweathermap
type WeatherData struct { type WeatherData struct {
City string `json:"name"` City string `json:"name"`
Main struct { Main struct {
Humidity int `json:"humidity"` Humidity int `json:"humidity"`
Pressure int `json:"pressure"` Pressure int `json:"pressure"`
Temperature float32 `json:"temp"` Temperature float32 `json:"temp"`
} `json:"main"` } `json:"main"`
Clouds struct { Clouds struct {
All int `json:"all"` All int `json:"all"`
} `json:"clouds"` } `json:"clouds"`
Rain struct { Rain struct {
OneHour float32 `json:"1h"` OneHour float32 `json:"1h"`
TreeHours float32 `json:"3h"` TreeHours float32 `json:"3h"`
} `json:"rain"` } `json:"rain"`
Snow struct { Snow struct {
OneHour float32 `json:"1h"` OneHour float32 `json:"1h"`
TreeHours float32 `json:"3h"` TreeHours float32 `json:"3h"`
} `json:"snow"` } `json:"snow"`
Wind struct { Wind struct {
Speed float32 `json:"speed"` Speed float32 `json:"speed"`
Direction int `json:"deg"` Direction int `json:"deg"`
} `json:"Wind"` } `json:"Wind"`
Sys struct { Sys struct {
Country string `json:"country"` Country string `json:"country"`
} `json:"sys"` } `json:"sys"`
} }
// FetchData from OpenWeatherMap API // FetchData from OpenWeatherMap API
func (w *Weather) FetchData() { func (w *Weather) FetchData() {
for _, city := range w.Config.Cities { for _, city := range w.Config.Cities {
resp, err := http.Get( resp, err := http.Get(
fmt.Sprintf( fmt.Sprintf(
"%s/weather?q=%s&appid=%s&units=%s", "%s/weather?q=%s&appid=%s&units=%s",
URI, URI,
city, city,
w.Config.OpenWeatherMap.APIKey, w.Config.OpenWeatherMap.APIKey,
w.Config.OpenWeatherMap.Units, w.Config.OpenWeatherMap.Units,
), ),
) )
if err != nil { if err != nil {
fmt.Printf("%s", err) fmt.Printf("%s", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
fmt.Printf("%s", err) fmt.Printf("%s", err)
} }
weatherData := WeatherData{} weatherData := WeatherData{}
json.Unmarshal(data, &weatherData) json.Unmarshal(data, &weatherData)
w.WeatherDatas = append(w.WeatherDatas, weatherData) w.WeatherDatas = append(w.WeatherDatas, weatherData)
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
} }
} }
// SendToInfluxDB send data in influxdb // SendToInfluxDB send data in influxdb
func (w *Weather) SendToInfluxDB() error { func (w *Weather) SendToInfluxDB() error {
conn, err := influx.NewHTTPClient(influx.HTTPConfig{ conn, err := influx.NewHTTPClient(influx.HTTPConfig{
Addr: w.Config.InfluxDB.URL, Addr: w.Config.InfluxDB.URL,
Username: w.Config.InfluxDB.Username, Username: w.Config.InfluxDB.Username,
Password: w.Config.InfluxDB.Password, Password: w.Config.InfluxDB.Password,
}) })
if err != nil { if err != nil {
return err return err
} }
defer conn.Close() defer conn.Close()
bps, _ := influx.NewBatchPoints( bps, _ := influx.NewBatchPoints(
influx.BatchPointsConfig{ influx.BatchPointsConfig{
Database: w.Config.InfluxDB.Database, Database: w.Config.InfluxDB.Database,
}) })
for _, weather := range w.WeatherDatas { for _, weather := range w.WeatherDatas {
tags := map[string]string{ "city": weather.City, "country": weather.Sys.Country } tags := map[string]string{"city": weather.City, "country": weather.Sys.Country}
fields := map[string]interface{}{ fields := map[string]interface{}{
"temperature": weather.Main.Temperature, "temperature": weather.Main.Temperature,
"humidity": weather.Main.Humidity, "humidity": weather.Main.Humidity,
"pressure": weather.Main.Pressure, "pressure": weather.Main.Pressure,
"clouds": weather.Clouds.All, "clouds": weather.Clouds.All,
"wind_speed": weather.Wind.Speed, "wind_speed": weather.Wind.Speed,
"wind_direction": weather.Wind.Direction, "wind_direction": weather.Wind.Direction,
"rain_1h": weather.Rain.OneHour, "rain_1h": weather.Rain.OneHour,
"rain_3h": weather.Rain.TreeHours, "rain_3h": weather.Rain.TreeHours,
"snow_1h": weather.Snow.OneHour, "snow_1h": weather.Snow.OneHour,
"snow_3h": weather.Snow.TreeHours, "snow_3h": weather.Snow.TreeHours,
} }
point, _ := influx.NewPoint(w.Config.InfluxDB.Measurement, tags, fields, time.Now()) point, _ := influx.NewPoint(w.Config.InfluxDB.Measurement, tags, fields, time.Now())
bps.AddPoint(point) bps.AddPoint(point)
} }
err = conn.Write(bps) err = conn.Write(bps)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }