| package main | |
| import ( | |
| "device-analytics/configuration" | |
| "device-analytics/data" | |
| "device-analytics/handlers" | |
| "device-analytics/logic" | |
| "flag" | |
| "fmt" | |
| "net/http" | |
| "os" | |
| "path" | |
| log "gerrit.wikimedia.org/r/mediawiki/services/servicelib-golang/logger" | |
| prometheusmiddleware "github.com/albertogviana/prometheus-middleware" | |
| "github.com/gorilla/mux" | |
| "github.com/prometheus/client_golang/prometheus/promhttp" | |
| "gitlab.wikimedia.org/repos/generated-data-platform/aqs/aqsassist" | |
| ) | |
| var ( | |
| // These values are assigned at build using `-ldflags` (see: Makefile) | |
| buildDate = "unknown" | |
| buildHost = "unknown" | |
| version = "unknown" | |
| ) | |
| // API documentation | |
| // @title Wikimedia Device Analytics | |
| // @version 1 | |
| // @description Device Analytics provides data about the number of unique devices that access Wikimedia projects. | |
| // @description Data provided by this API is available under the [CC0 1.0 license](https://creativecommons.org/publicdomain/zero/1.0/). | |
| // @termsOfService https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Terms_of_Use | |
| // @host wikimedia.org | |
| // @basePath /api/rest_v1/metrics | |
| // @schemes https | |
| // Entrypoint for the service | |
| func main() { | |
| var confFile = flag.String("config", "./config.yaml", aqsassist.ConfigurationPathMessage) | |
| var config *configuration.Config | |
| var err error | |
| var uniqueDevicesData data.UniqueDevicesData | |
| var uniqueDeviceslogic = logic.NewUniqueDevicesLogic(uniqueDevicesData) | |
| flag.Parse() | |
| if config, err = configuration.ReadConfig(*confFile); err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| logger, err := log.NewLogger(os.Stdout, config.ServiceName, config.LogLevel) | |
| if err != nil { | |
| fmt.Fprintf(os.Stderr, aqsassist.ErrorInitializingLoggerMessage, err) | |
| os.Exit(1) | |
| } | |
| // Allow overriding config using environment variables | |
| MergeEnvironment(config, logger) | |
| aqsassist.LogCassandraServiceInitialization(logger, config.ServiceName, version, buildHost, buildDate, config.Cassandra.Hosts, | |
| config.Cassandra.Port, config.Cassandra.Consistency, config.Cassandra.LocalDC) | |
| session, err := newCassandraSession(config) | |
| if err != nil { | |
| logger.Error(aqsassist.CassandraConnectionErrorMessage, err) | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| // pass bound struct method to handler | |
| uniqueDevicesHandler := &handlers.UniqueDevicesHandler{ | |
| Logger: logger, Session: session, Logic: &uniqueDeviceslogic, Config: config} | |
| apiSpecHandler := &handlers.ApiSpecHandler{ | |
| Logger: logger} | |
| healthz := NewHealthz(version, buildDate, buildHost) | |
| middleware := prometheusmiddleware.NewPrometheusMiddleware(prometheusmiddleware.Opts{}) | |
| r := mux.NewRouter().SkipClean(true).UseEncodedPath() | |
| r.NotFoundHandler = http.HandlerFunc(handlers.NotFoundHandler) | |
| p := promhttp.Handler() | |
| r.Use(SetSecurityHeaders, ValidateProject, middleware.InstrumentHandlerDuration) | |
| r.Handle("/metrics", p).Methods("GET") | |
| r.HandleFunc("/healthz", healthz.HandleHTTP).Methods("GET") | |
| r.HandleFunc("/device-analytics/api-spec.json", apiSpecHandler.HandleHTTP).Methods("GET") | |
| r.HandleFunc(path.Join(config.BaseURI, "/{project}/{access-site}/{granularity}/{start}/{end}"), uniqueDevicesHandler.HandleHTTP).Methods("GET") | |
| srv := &http.Server{ | |
| Addr: fmt.Sprintf("%s:%d", config.Address, config.Port), | |
| Handler: r, | |
| } | |
| err = srv.ListenAndServe() | |
| fmt.Println(err.Error()) | |
| } |
US