From a0d940f8cdb354d439943e07c848f4bc8c5011eb Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Fri, 26 Aug 2016 22:08:53 +0300 Subject: [PATCH 01/11] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B8=D1=82=D1=8C=20sta?= =?UTF-8?q?tsd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/statsd/.gitignore | 2 ++ docker-compose.base.yml | 5 +++++ docker-compose.dev.yml | 8 ++++++++ lib/routes/Textures.go | 1 + lib/services/services.go | 3 +++ minecraft-skinsystem.go | 14 ++++++++++++++ 6 files changed, 33 insertions(+) create mode 100644 data/statsd/.gitignore diff --git a/data/statsd/.gitignore b/data/statsd/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/data/statsd/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker-compose.base.yml b/docker-compose.base.yml index d8df429..1ffb478 100644 --- a/docker-compose.base.yml +++ b/docker-compose.base.yml @@ -11,3 +11,8 @@ services: RABBITMQ_DEFAULT_USER: "ely-skinsystem-app" RABBITMQ_DEFAULT_PASS: "ely-skinsystem-app-password" RABBITMQ_DEFAULT_VHOST: "/ely" + + statsd: + image: hopsoft/graphite-statsd + volumes: + - ./data/statsd:/opt/graphite/storage diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index db6d8c0..c5e919d 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -11,6 +11,7 @@ services: links: - redis - rabbitmq + - statsd redis: extends: @@ -21,3 +22,10 @@ services: extends: file: docker-compose.base.yml service: rabbitmq + + statsd: + extends: + file: docker-compose.base.yml + service: statsd + ports: + - "8123:80" diff --git a/lib/routes/Textures.go b/lib/routes/Textures.go index b1cd1ae..e0c10fc 100644 --- a/lib/routes/Textures.go +++ b/lib/routes/Textures.go @@ -13,6 +13,7 @@ import ( ) func Textures(w http.ResponseWriter, r *http.Request) { + services.Stats.Incr("textures-requests", 1) username := tools.ParseUsername(mux.Vars(r)["username"]) log.Println("request textures for username " + username) diff --git a/lib/services/services.go b/lib/services/services.go index e4ce93d..c1906d6 100644 --- a/lib/services/services.go +++ b/lib/services/services.go @@ -4,6 +4,7 @@ import ( "github.com/mediocregopher/radix.v2/pool" "github.com/streadway/amqp" "github.com/gorilla/mux" + "github.com/quipo/statsd" ) var Router *mux.Router @@ -13,3 +14,5 @@ var RedisPool *pool.Pool var RabbitMQChannel *amqp.Channel var RootFolder string + +var Stats *statsd.StatsdBuffer diff --git a/minecraft-skinsystem.go b/minecraft-skinsystem.go index 9f90837..a125015 100644 --- a/minecraft-skinsystem.go +++ b/minecraft-skinsystem.go @@ -11,6 +11,8 @@ import ( "github.com/gorilla/mux" "github.com/streadway/amqp" "github.com/mediocregopher/radix.v2/pool" + "github.com/quipo/statsd" + //"github.com/mediocregopher/radix.v2/redis" "elyby/minecraft-skinsystem/lib/routes" "elyby/minecraft-skinsystem/lib/services" @@ -56,6 +58,17 @@ func main() { } log.Println("Connected to rabbitmq channel") + // init + statsClient := statsd.NewStatsdClient(statsString, "skinsystem.") + statsErr := statsClient.CreateSocket() + if statsErr != nil { + log.Fatal(statsErr) + } + + interval := 2 * time.Second // aggregate stats and flush every 2 seconds + stats := statsd.NewStatsdBuffer(interval, statsClient) + defer stats.Close() + router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/skins/{username}", routes.Skin).Methods("GET").Name("skins") router.HandleFunc("/cloaks/{username}", routes.Cape).Methods("GET").Name("cloaks") @@ -75,6 +88,7 @@ func main() { services.Router = router services.RedisPool = redisPool services.RabbitMQChannel = rabbitChannel + services.Stats = stats _, file, _, _ := runtime.Caller(0) services.RootFolder = filepath.Dir(file) From 66c61dc3cd091812c8c7ac1b871d4f1338b5758c Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 3 Dec 2016 01:57:55 +0300 Subject: [PATCH 02/11] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BB=D0=BE=D0=B3=D0=B3=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B5=D1=82=D1=80=D0=B8?= =?UTF-8?q?=D0=BA=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B8=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=BC=D1=8B=20=D1=81=D0=BA=D0=B8=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/SkinItem.go | 3 +++ lib/routes/Cape.go | 9 +++++++-- lib/routes/Face.go | 2 -- lib/routes/MinecraftPHP.go | 14 ++++++++++---- lib/routes/Skin.go | 9 +++++++-- lib/routes/Textures.go | 3 +-- lib/services/services.go | 4 ++-- lib/worker/handlers.go | 10 +++++++--- minecraft-skinsystem.go | 33 ++++++++++++++++++++++----------- 9 files changed, 59 insertions(+), 28 deletions(-) diff --git a/lib/data/SkinItem.go b/lib/data/SkinItem.go index 8ad55d7..6e0eabb 100644 --- a/lib/data/SkinItem.go +++ b/lib/data/SkinItem.go @@ -62,13 +62,16 @@ func (s *SkinItem) Delete() { func FindSkinByUsername(username string) (SkinItem, error) { var record SkinItem; + services.Logger.IncCounter("skins.storage.query", 1) response := services.RedisPool.Cmd("GET", tools.BuildKey(username)); if (response.IsType(redis.Nil)) { + services.Logger.IncCounter("skins.storage.not_found", 1) return record, SkinNotFound{username} } result, err := response.Str() if (err == nil) { + services.Logger.IncCounter("skins.storage.found", 1) decodeErr := json.Unmarshal([]byte(result), &record) if (decodeErr != nil) { log.Println("Cannot decode record data") diff --git a/lib/routes/Cape.go b/lib/routes/Cape.go index 9d87832..ade4d55 100644 --- a/lib/routes/Cape.go +++ b/lib/routes/Cape.go @@ -2,18 +2,21 @@ package routes import ( "io" - "log" "net/http" "github.com/gorilla/mux" "elyby/minecraft-skinsystem/lib/tools" "elyby/minecraft-skinsystem/lib/data" + "elyby/minecraft-skinsystem/lib/services" ) func Cape(response http.ResponseWriter, request *http.Request) { + if (mux.Vars(request)["converted"] == "") { + services.Logger.IncCounter("capes.request", 1) + } + username := tools.ParseUsername(mux.Vars(request)["username"]) - log.Println("request cape for username " + username) rec, err := data.FindCapeByUsername(username) if (err != nil) { http.Redirect(response, request, "http://skins.minecraft.net/MinecraftCloaks/" + username + ".png", 301) @@ -24,6 +27,7 @@ func Cape(response http.ResponseWriter, request *http.Request) { } func CapeGET(w http.ResponseWriter, r *http.Request) { + services.Logger.IncCounter("capes.get-request", 1) username := r.URL.Query().Get("name") if username == "" { w.WriteHeader(http.StatusBadRequest) @@ -31,5 +35,6 @@ func CapeGET(w http.ResponseWriter, r *http.Request) { } mux.Vars(r)["username"] = username + mux.Vars(r)["converted"] = "1" Cape(w, r) } diff --git a/lib/routes/Face.go b/lib/routes/Face.go index 574d1e4..24a662d 100644 --- a/lib/routes/Face.go +++ b/lib/routes/Face.go @@ -1,7 +1,6 @@ package routes import ( - "log" "net/http" "github.com/gorilla/mux" @@ -14,7 +13,6 @@ const defaultHash = "default" func Face(w http.ResponseWriter, r *http.Request) { username := tools.ParseUsername(mux.Vars(r)["username"]) - log.Println("request skin for username " + username); rec, err := data.FindSkinByUsername(username) var hash string if (err != nil || rec.SkinId == 0) { diff --git a/lib/routes/MinecraftPHP.go b/lib/routes/MinecraftPHP.go index 3457662..dc237df 100644 --- a/lib/routes/MinecraftPHP.go +++ b/lib/routes/MinecraftPHP.go @@ -4,6 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + + "elyby/minecraft-skinsystem/lib/services" ) // Метод-наследие от первой версии системы скинов. @@ -18,11 +20,15 @@ func MinecraftPHP(w http.ResponseWriter, r *http.Request) { } mux.Vars(r)["username"] = username + mux.Vars(r)["converted"] = "1" switch required { - case "skin": Skin(w, r) - case "cloack": Cape(w, r) - default: { + case "skin": + services.Logger.IncCounter("skins.minecraft-php-request", 1) + Skin(w, r) + case "cloack": + services.Logger.IncCounter("capes.minecraft-php-request", 1) + Cape(w, r) + default: w.WriteHeader(http.StatusNotFound) } - } } diff --git a/lib/routes/Skin.go b/lib/routes/Skin.go index 97a1e5c..5eab058 100644 --- a/lib/routes/Skin.go +++ b/lib/routes/Skin.go @@ -1,18 +1,21 @@ package routes import ( - "log" "net/http" "github.com/gorilla/mux" "elyby/minecraft-skinsystem/lib/tools" "elyby/minecraft-skinsystem/lib/data" + "elyby/minecraft-skinsystem/lib/services" ) func Skin(w http.ResponseWriter, r *http.Request) { + if (mux.Vars(r)["converted"] == "") { + services.Logger.IncCounter("skins.request", 1) + } + username := tools.ParseUsername(mux.Vars(r)["username"]) - log.Println("request skin for username " + username); rec, err := data.FindSkinByUsername(username) if (err != nil) { http.Redirect(w, r, "http://skins.minecraft.net/MinecraftSkins/" + username + ".png", 301) @@ -23,6 +26,7 @@ func Skin(w http.ResponseWriter, r *http.Request) { } func SkinGET(w http.ResponseWriter, r *http.Request) { + services.Logger.IncCounter("skins.get-request", 1) username := r.URL.Query().Get("name") if username == "" { w.WriteHeader(http.StatusBadRequest) @@ -30,5 +34,6 @@ func SkinGET(w http.ResponseWriter, r *http.Request) { } mux.Vars(r)["username"] = username + mux.Vars(r)["converted"] = "1" Skin(w, r) } diff --git a/lib/routes/Textures.go b/lib/routes/Textures.go index e0c10fc..7d324fb 100644 --- a/lib/routes/Textures.go +++ b/lib/routes/Textures.go @@ -13,9 +13,8 @@ import ( ) func Textures(w http.ResponseWriter, r *http.Request) { - services.Stats.Incr("textures-requests", 1) + services.Logger.IncCounter("textures.request", 1) username := tools.ParseUsername(mux.Vars(r)["username"]) - log.Println("request textures for username " + username) rec, err := data.FindSkinByUsername(username) if (err != nil || rec.SkinId == 0) { diff --git a/lib/services/services.go b/lib/services/services.go index c1906d6..07e8c70 100644 --- a/lib/services/services.go +++ b/lib/services/services.go @@ -4,7 +4,7 @@ import ( "github.com/mediocregopher/radix.v2/pool" "github.com/streadway/amqp" "github.com/gorilla/mux" - "github.com/quipo/statsd" + "github.com/mono83/slf/wd" ) var Router *mux.Router @@ -15,4 +15,4 @@ var RabbitMQChannel *amqp.Channel var RootFolder string -var Stats *statsd.StatsdBuffer +var Logger wd.Watchdog diff --git a/lib/worker/handlers.go b/lib/worker/handlers.go index 36186f8..3b0abaf 100644 --- a/lib/worker/handlers.go +++ b/lib/worker/handlers.go @@ -2,11 +2,12 @@ package worker import ( "elyby/minecraft-skinsystem/lib/data" - "log" + "elyby/minecraft-skinsystem/lib/services" ) func handleChangeUsername(model usernameChanged) (bool) { if (model.OldUsername == "") { + services.Logger.IncCounter("worker.change_username.empty_old_username") record := data.SkinItem{ UserId: model.AccountId, Username: model.NewUsername, @@ -19,7 +20,7 @@ func handleChangeUsername(model usernameChanged) (bool) { record, err := data.FindSkinByUsername(model.OldUsername) if (err != nil) { - log.Println("Exit by not found record") + services.Logger.IncCounter("worker.change_username.username_not_found") // TODO: я не уверен, что это валидное поведение // Суть в том, что здесь может возникнуть ошибка в том случае, если записи в базе нету // а значит его нужно, как минимум, зарегистрировать @@ -29,7 +30,7 @@ func handleChangeUsername(model usernameChanged) (bool) { record.Username = model.NewUsername record.Save() - log.Println("all saved!") + services.Logger.IncCounter("worker.change_username.processed") return true } @@ -37,6 +38,7 @@ func handleChangeUsername(model usernameChanged) (bool) { func handleSkinChanged(model skinChanged) (bool) { record, err := data.FindSkinById(model.AccountId) if (err != nil) { + services.Logger.IncCounter("worker.skin_changed.id_not_found") return true } @@ -48,5 +50,7 @@ func handleSkinChanged(model skinChanged) (bool) { record.Save() + services.Logger.IncCounter("worker.skin_changed.processed") + return true } diff --git a/minecraft-skinsystem.go b/minecraft-skinsystem.go index a125015..7ee7e7a 100644 --- a/minecraft-skinsystem.go +++ b/minecraft-skinsystem.go @@ -11,8 +11,10 @@ import ( "github.com/gorilla/mux" "github.com/streadway/amqp" "github.com/mediocregopher/radix.v2/pool" - "github.com/quipo/statsd" - //"github.com/mediocregopher/radix.v2/redis" + "github.com/mono83/slf/wd" + "github.com/mono83/slf/rays" + "github.com/mono83/slf/recievers/ansi" + "github.com/mono83/slf/recievers/statsd" "elyby/minecraft-skinsystem/lib/routes" "elyby/minecraft-skinsystem/lib/services" @@ -58,16 +60,25 @@ func main() { } log.Println("Connected to rabbitmq channel") - // init - statsClient := statsd.NewStatsdClient(statsString, "skinsystem.") - statsErr := statsClient.CreateSocket() - if statsErr != nil { - log.Fatal(statsErr) + // statsd + var statsdString = os.Getenv("STATSD_ADDR") + if (statsdString != "") { + hostname, _ := os.Hostname() + statsdReceiver, err := statsd.NewReceiver(statsd.Config{ + Address: statsdString, + Prefix: "ely.skinsystem." + hostname + ".", + FlushEvery: 2, + }) + if (err != nil) { + log.Fatal("statsd connection error") + } + + wd.AddReceiver(statsdReceiver) + } else { + wd.AddReceiver(ansi.New(true, true, false)) } - interval := 2 * time.Second // aggregate stats and flush every 2 seconds - stats := statsd.NewStatsdBuffer(interval, statsClient) - defer stats.Close() + logger := wd.New("", "").WithParams(rays.Host) router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/skins/{username}", routes.Skin).Methods("GET").Name("skins") @@ -88,7 +99,7 @@ func main() { services.Router = router services.RedisPool = redisPool services.RabbitMQChannel = rabbitChannel - services.Stats = stats + services.Logger = logger _, file, _, _ := runtime.Caller(0) services.RootFolder = filepath.Dir(file) From 1694403c790cea0bcbe674eb1f07f54e6ed71246 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 3 Dec 2016 02:05:23 +0300 Subject: [PATCH 03/11] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20gitlab-ci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..96ed414 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,33 @@ +image: docker:latest + +stages: + - build + - push + +before_script: + - docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by + +variables: + CONTAINER_IMAGE: registry.ely.by/elyby/skinsystem + +build: + stage: build + script: + - export IMAGE_NAME="$CONTAINER_IMAGE:dev" + - docker build --pull -t $IMAGE_NAME . + - docker push $IMAGE_NAME + only: + - develop + +push_tags: + stage: push + variables: + GIT_STRATEGY: none + script: + - export IMAGE_NAME="$CONTAINER_IMAGE:$CI_BUILD_TAG" + - docker tag $CONTAINER_IMAGE:dev $CONTAINER_IMAGE:latest + - docker tag $CONTAINER_IMAGE:latest $IMAGE_NAME + - docker push $IMAGE_NAME + - docker push $CONTAINER_IMAGE:latest + only: + - tags From 5d46094643fcdb00812670d82b55e49ee2889685 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 3 Dec 2016 02:08:00 +0300 Subject: [PATCH 04/11] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D1=91=D0=BD=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0?= =?UTF-8?q?=20setSkin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/SetSkin.go | 29 ----------------------------- minecraft-skinsystem.go | 3 --- 2 files changed, 32 deletions(-) delete mode 100644 lib/routes/SetSkin.go diff --git a/lib/routes/SetSkin.go b/lib/routes/SetSkin.go deleted file mode 100644 index b1acb87..0000000 --- a/lib/routes/SetSkin.go +++ /dev/null @@ -1,29 +0,0 @@ -package routes - -import ( - "net/http" - "strconv" - - "elyby/minecraft-skinsystem/lib/data" -) - -func SetSkin(w http.ResponseWriter, r *http.Request) { - key := r.Header.Get("X-Ely-key") - if key != "43fd2ce61b3f5704dfd729c1f2d6ffdb" { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("Nice try")) - return - } - - skin := new(data.SkinItem) - skin.Username = r.PostFormValue("username") - skin.UserId, _ = strconv.Atoi(r.PostFormValue("userId")) - skin.SkinId, _ = strconv.Atoi(r.PostFormValue("skinId")) - skin.Hash = r.PostFormValue("hash") - skin.Is1_8, _ = strconv.ParseBool(r.PostFormValue("is1_8")) - skin.IsSlim, _ = strconv.ParseBool(r.PostFormValue("isSlim")) - skin.Url = r.PostFormValue("url") - skin.Save() - - w.Write([]byte("OK")) -} diff --git a/minecraft-skinsystem.go b/minecraft-skinsystem.go index 9f90837..9aa1bc1 100644 --- a/minecraft-skinsystem.go +++ b/minecraft-skinsystem.go @@ -69,9 +69,6 @@ func main() { // 404 router.NotFoundHandler = http.HandlerFunc(routes.NotFound) - apiRouter := router.PathPrefix("/api").Subrouter() - apiRouter.HandleFunc("/user/{username}/skin", routes.SetSkin).Methods("POST") - services.Router = router services.RedisPool = redisPool services.RabbitMQChannel = rabbitChannel From 201a257d69e83c34e95b355d61c58df50ce29f1b Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 25 Mar 2017 15:54:17 +0300 Subject: [PATCH 05/11] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=20IncCounter=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B4=D0=B0=D1=87=20=D0=B8=D0=B7=20amqp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/worker/handlers.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/worker/handlers.go b/lib/worker/handlers.go index 3b0abaf..b573275 100644 --- a/lib/worker/handlers.go +++ b/lib/worker/handlers.go @@ -7,7 +7,7 @@ import ( func handleChangeUsername(model usernameChanged) (bool) { if (model.OldUsername == "") { - services.Logger.IncCounter("worker.change_username.empty_old_username") + services.Logger.IncCounter("worker.change_username.empty_old_username", 1) record := data.SkinItem{ UserId: model.AccountId, Username: model.NewUsername, @@ -20,7 +20,7 @@ func handleChangeUsername(model usernameChanged) (bool) { record, err := data.FindSkinByUsername(model.OldUsername) if (err != nil) { - services.Logger.IncCounter("worker.change_username.username_not_found") + services.Logger.IncCounter("worker.change_username.username_not_found", 1) // TODO: я не уверен, что это валидное поведение // Суть в том, что здесь может возникнуть ошибка в том случае, если записи в базе нету // а значит его нужно, как минимум, зарегистрировать @@ -30,7 +30,7 @@ func handleChangeUsername(model usernameChanged) (bool) { record.Username = model.NewUsername record.Save() - services.Logger.IncCounter("worker.change_username.processed") + services.Logger.IncCounter("worker.change_username.processed", 1) return true } @@ -38,7 +38,7 @@ func handleChangeUsername(model usernameChanged) (bool) { func handleSkinChanged(model skinChanged) (bool) { record, err := data.FindSkinById(model.AccountId) if (err != nil) { - services.Logger.IncCounter("worker.skin_changed.id_not_found") + services.Logger.IncCounter("worker.skin_changed.id_not_found", 1) return true } @@ -50,7 +50,7 @@ func handleSkinChanged(model skinChanged) (bool) { record.Save() - services.Logger.IncCounter("worker.skin_changed.processed") + services.Logger.IncCounter("worker.skin_changed.processed", 1) return true } From 6a881a62e3e4f06610116820cceee1952d100f75 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 25 Mar 2017 15:55:57 +0300 Subject: [PATCH 06/11] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3?= =?UTF-8?q?=D1=83=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B2=D0=B7=D0=B0=D0=B8?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=81=D0=BE=20statsd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- minecraft-skinsystem.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/minecraft-skinsystem.go b/minecraft-skinsystem.go index 7ee7e7a..989f7a8 100644 --- a/minecraft-skinsystem.go +++ b/minecraft-skinsystem.go @@ -63,11 +63,12 @@ func main() { // statsd var statsdString = os.Getenv("STATSD_ADDR") if (statsdString != "") { + log.Println("Connecting to statsd") hostname, _ := os.Hostname() statsdReceiver, err := statsd.NewReceiver(statsd.Config{ Address: statsdString, - Prefix: "ely.skinsystem." + hostname + ".", - FlushEvery: 2, + Prefix: "ely.skinsystem." + hostname + ".app.", + FlushEvery: 1, }) if (err != nil) { log.Fatal("statsd connection error") From c74151c5588945f2902c51073b8d3fc1edaafb7f Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 25 Mar 2017 16:36:37 +0300 Subject: [PATCH 07/11] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B=20=D0=BD=D0=B5=D0=BA?= =?UTF-8?q?=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B5=20=D0=BF=D0=B0=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D1=80=D1=8B=20=D0=B4=D0=BB=D1=8F=20statsd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/SkinItem.go | 6 +++--- lib/routes/Cape.go | 2 +- lib/routes/Skin.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/data/SkinItem.go b/lib/data/SkinItem.go index 6e0eabb..cc19253 100644 --- a/lib/data/SkinItem.go +++ b/lib/data/SkinItem.go @@ -62,16 +62,16 @@ func (s *SkinItem) Delete() { func FindSkinByUsername(username string) (SkinItem, error) { var record SkinItem; - services.Logger.IncCounter("skins.storage.query", 1) + services.Logger.IncCounter("storage.query", 1) response := services.RedisPool.Cmd("GET", tools.BuildKey(username)); if (response.IsType(redis.Nil)) { - services.Logger.IncCounter("skins.storage.not_found", 1) + services.Logger.IncCounter("storage.not_found", 1) return record, SkinNotFound{username} } result, err := response.Str() if (err == nil) { - services.Logger.IncCounter("skins.storage.found", 1) + services.Logger.IncCounter("storage.found", 1) decodeErr := json.Unmarshal([]byte(result), &record) if (decodeErr != nil) { log.Println("Cannot decode record data") diff --git a/lib/routes/Cape.go b/lib/routes/Cape.go index ade4d55..d0560ca 100644 --- a/lib/routes/Cape.go +++ b/lib/routes/Cape.go @@ -27,7 +27,7 @@ func Cape(response http.ResponseWriter, request *http.Request) { } func CapeGET(w http.ResponseWriter, r *http.Request) { - services.Logger.IncCounter("capes.get-request", 1) + services.Logger.IncCounter("capes.get_request", 1) username := r.URL.Query().Get("name") if username == "" { w.WriteHeader(http.StatusBadRequest) diff --git a/lib/routes/Skin.go b/lib/routes/Skin.go index 5eab058..49f3a31 100644 --- a/lib/routes/Skin.go +++ b/lib/routes/Skin.go @@ -26,7 +26,7 @@ func Skin(w http.ResponseWriter, r *http.Request) { } func SkinGET(w http.ResponseWriter, r *http.Request) { - services.Logger.IncCounter("skins.get-request", 1) + services.Logger.IncCounter("skins.get_request", 1) username := r.URL.Query().Get("name") if username == "" { w.WriteHeader(http.StatusBadRequest) From d3b4bee3b0fb5b9c319a70a1a0ff6bb6d07a8549 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 25 Mar 2017 16:48:47 +0300 Subject: [PATCH 08/11] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D1=91=D0=BD=20docker-composer.base.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.base.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.base.yml b/docker-compose.base.yml index 1ffb478..2183345 100644 --- a/docker-compose.base.yml +++ b/docker-compose.base.yml @@ -16,3 +16,5 @@ services: image: hopsoft/graphite-statsd volumes: - ./data/statsd:/opt/graphite/storage + - ./data/graphite-config:/opt/graphite/conf + - ./data/statsd-config/config.json:/opt/statsd/config.js From e652691b298a20acc4f8d115c406fdab081d32bf Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 1 Apr 2017 12:18:57 +0300 Subject: [PATCH 09/11] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D1=83?= =?UTF-8?q?=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/SignedTexturesResponse.go | 14 +++++++++++ lib/data/SkinItem.go | 19 ++++++++------ lib/routes/SignedTextures.go | 40 ++++++++++++++++++++++++++++++ lib/worker/handlers.go | 9 ++++--- lib/worker/models.go | 17 +++++++------ minecraft-skinsystem.go | 1 + 6 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 lib/data/SignedTexturesResponse.go create mode 100644 lib/routes/SignedTextures.go diff --git a/lib/data/SignedTexturesResponse.go b/lib/data/SignedTexturesResponse.go new file mode 100644 index 0000000..cf0ec16 --- /dev/null +++ b/lib/data/SignedTexturesResponse.go @@ -0,0 +1,14 @@ +package data + +type SignedTexturesResponse struct { + Id string `json:"id"` + Name string `json:"name"` + IsEly bool `json:"ely,omitempty"` + Props []Property `json:"properties"` +} + +type Property struct { + Name string `json:"name"` + Signature string `json:"signature"` + Value string `json:"value"` +} diff --git a/lib/data/SkinItem.go b/lib/data/SkinItem.go index cc19253..eb88735 100644 --- a/lib/data/SkinItem.go +++ b/lib/data/SkinItem.go @@ -12,14 +12,17 @@ import ( ) type SkinItem struct { - UserId int `json:"userId"` - Username string `json:"username"` - SkinId int `json:"skinId"` - Url string `json:"url"` - Is1_8 bool `json:"is1_8"` - IsSlim bool `json:"isSlim"` - Hash string `json:"hash"` - oldUsername string + UserId int `json:"userId"` + Uuid string `json:"uuid"` + Username string `json:"username"` + SkinId int `json:"skinId"` + Url string `json:"url"` + Is1_8 bool `json:"is1_8"` + IsSlim bool `json:"isSlim"` + Hash string `json:"hash"` + MojangTextures string `json:"mojangTextures"` + MojangSignature string `json:"mojangSignature"` + oldUsername string } const accountIdToUsernameKey string = "hash:username-to-account-id" diff --git a/lib/routes/SignedTextures.go b/lib/routes/SignedTextures.go new file mode 100644 index 0000000..750a515 --- /dev/null +++ b/lib/routes/SignedTextures.go @@ -0,0 +1,40 @@ +package routes + +import ( + "strings" + "net/http" + "encoding/json" + + "github.com/gorilla/mux" + + "elyby/minecraft-skinsystem/lib/data" + "elyby/minecraft-skinsystem/lib/tools" + "elyby/minecraft-skinsystem/lib/services" +) + +func SignedTextures(w http.ResponseWriter, r *http.Request) { + services.Logger.IncCounter("signed_textures.request", 1) + username := tools.ParseUsername(mux.Vars(r)["username"]) + + rec, err := data.FindSkinByUsername(username) + if (err != nil || rec.SkinId == 0) { + w.WriteHeader(http.StatusNoContent) + return + } + + responseData:= data.SignedTexturesResponse{ + Id: strings.Replace(rec.Uuid, "-", "", -1), + Name: rec.Username, + Props: []data.Property{ + { + Name: "textures", + Signature: rec.MojangSignature, + Value: rec.MojangTextures, + }, + }, + } + + response,_ := json.Marshal(responseData) + w.Header().Set("Content-Type", "application/json") + w.Write(response) +} diff --git a/lib/worker/handlers.go b/lib/worker/handlers.go index b573275..072fefd 100644 --- a/lib/worker/handlers.go +++ b/lib/worker/handlers.go @@ -42,11 +42,14 @@ func handleSkinChanged(model skinChanged) (bool) { return true } + record.Uuid = model.Uuid record.SkinId = model.SkinId - record.Hash = model.Hash - record.Is1_8 = model.Is1_8 + record.Hash = model.Hash + record.Is1_8 = model.Is1_8 record.IsSlim = model.IsSlim - record.Url = model.Url + record.Url = model.Url + record.MojangTextures = model.MojangTextures + record.MojangSignature = model.MojangSignature record.Save() diff --git a/lib/worker/models.go b/lib/worker/models.go index eede2c2..0844112 100644 --- a/lib/worker/models.go +++ b/lib/worker/models.go @@ -7,11 +7,14 @@ type usernameChanged struct { } type skinChanged struct { - AccountId int `json:"userId"` - SkinId int `json:"skinId"` - OldSkinId int `json:"oldSkinId"` - Hash string `json:"hash"` - Is1_8 bool `json:"is1_8"` - IsSlim bool `json:"isSlim"` - Url string `json:"url"` + AccountId int `json:"userId"` + Uuid string `json:"uuid"` + SkinId int `json:"skinId"` + OldSkinId int `json:"oldSkinId"` + Hash string `json:"hash"` + Is1_8 bool `json:"is1_8"` + IsSlim bool `json:"isSlim"` + Url string `json:"url"` + MojangTextures string `json:"mojangTextures"` + MojangSignature string `json:"mojangSignature"` } diff --git a/minecraft-skinsystem.go b/minecraft-skinsystem.go index 8f93a9a..b8eefb6 100644 --- a/minecraft-skinsystem.go +++ b/minecraft-skinsystem.go @@ -85,6 +85,7 @@ func main() { router.HandleFunc("/skins/{username}", routes.Skin).Methods("GET").Name("skins") router.HandleFunc("/cloaks/{username}", routes.Cape).Methods("GET").Name("cloaks") router.HandleFunc("/textures/{username}", routes.Textures).Methods("GET").Name("textures") + router.HandleFunc("/textures/signed/{username}", routes.SignedTextures).Methods("GET").Name("signedTextures") router.HandleFunc("/skins/{username}/face", routes.Face).Methods("GET").Name("faces") router.HandleFunc("/skins/{username}/face.png", routes.Face).Methods("GET").Name("faces") // Legacy From 39f5ec5bee345fde3341f07ad159c7c4f2940362 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 1 Apr 2017 12:22:48 +0300 Subject: [PATCH 10/11] =?UTF-8?q?=D0=A3=D1=87=D0=B8=D1=82=D1=8B=D0=B2?= =?UTF-8?q?=D0=B0=D0=B5=D0=BC=20=D1=81=D0=B8=D1=82=D1=83=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E,=20=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20=D1=81=D0=BA=D0=B8?= =?UTF-8?q?=D0=BD=20=D0=B5=D1=81=D1=82=D1=8C,=20=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D1=87=D0=B8=D1=82=D0=B0=D0=BD=D0=BD=D0=BE=D0=B9=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BA=D1=81=D1=82=D1=83=D1=80=D1=8B=20-=20=D0=BD?= =?UTF-8?q?=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/SignedTextures.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/routes/SignedTextures.go b/lib/routes/SignedTextures.go index 750a515..090a32f 100644 --- a/lib/routes/SignedTextures.go +++ b/lib/routes/SignedTextures.go @@ -17,7 +17,7 @@ func SignedTextures(w http.ResponseWriter, r *http.Request) { username := tools.ParseUsername(mux.Vars(r)["username"]) rec, err := data.FindSkinByUsername(username) - if (err != nil || rec.SkinId == 0) { + if (err != nil || rec.SkinId == 0 || rec.MojangTextures == "") { w.WriteHeader(http.StatusNoContent) return } From 3d73cc9402eb33815b7ca35cad1ae6f5f0b38a94 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sat, 1 Apr 2017 12:46:25 +0300 Subject: [PATCH 11/11] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20Ely=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/SignedTexturesResponse.go | 2 +- lib/routes/SignedTextures.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/data/SignedTexturesResponse.go b/lib/data/SignedTexturesResponse.go index cf0ec16..4c5eef9 100644 --- a/lib/data/SignedTexturesResponse.go +++ b/lib/data/SignedTexturesResponse.go @@ -9,6 +9,6 @@ type SignedTexturesResponse struct { type Property struct { Name string `json:"name"` - Signature string `json:"signature"` + Signature string `json:"signature,omitempty"` Value string `json:"value"` } diff --git a/lib/routes/SignedTextures.go b/lib/routes/SignedTextures.go index 090a32f..916042b 100644 --- a/lib/routes/SignedTextures.go +++ b/lib/routes/SignedTextures.go @@ -31,6 +31,10 @@ func SignedTextures(w http.ResponseWriter, r *http.Request) { Signature: rec.MojangSignature, Value: rec.MojangTextures, }, + { + Name: "ely", + Value: "but why are you asking?", + }, }, }