mnemonics 소스 추가
This commit is contained in:
parent
7fbf716eed
commit
96f8d6f794
|
@ -121,4 +121,4 @@ $RECYCLE.BIN/
|
||||||
|
|
||||||
build/
|
build/
|
||||||
bind/
|
bind/
|
||||||
wiki
|
mnemonics
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ImportPath": "amuz.es/go/wiki",
|
"ImportPath": "amuz.es/go/mnemonics",
|
||||||
"GoVersion": "go1.5",
|
"GoVersion": "go1.5",
|
||||||
"Deps": [
|
"Deps": [
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,11 @@
|
||||||
"ImportPath": "github.com/manucorporat/sse",
|
"ImportPath": "github.com/manucorporat/sse",
|
||||||
"Rev": "ee05b128a739a0fb76c7ebd3ae4810c1de808d6d"
|
"Rev": "ee05b128a739a0fb76c7ebd3ae4810c1de808d6d"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/zalando-techmonkeys/gin-glog",
|
||||||
|
"Comment": "1.0.2-10-g3a91815",
|
||||||
|
"Rev": "3a9181566c628311ad5453b06d5f6934a1fec92c"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/context",
|
"ImportPath": "golang.org/x/net/context",
|
||||||
"Rev": "08f168e593b5aab61849054b77981de812666697"
|
"Rev": "08f168e593b5aab61849054b77981de812666697"
|
||||||
|
|
24
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/.gitignore
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
12
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/.travis.yml
generated
vendored
Normal file
12
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.4
|
||||||
|
- 1.4.2
|
||||||
|
- tip
|
||||||
|
before_install:
|
||||||
|
- go get github.com/axw/gocov/gocov
|
||||||
|
- go get github.com/mattn/goveralls
|
||||||
|
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||||
|
script:
|
||||||
|
- $HOME/gopath/bin/goveralls -service=travis-ci
|
||||||
|
|
21
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/LICENSE
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Zalando SE
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
3
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/MAINTAINERS
generated
vendored
Normal file
3
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/MAINTAINERS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Sandor Szücs <sandor.szuecs@zalando.de>
|
||||||
|
Raffaele Di Fazio <raffaele.di.fazio@zalando.de>
|
||||||
|
Nick Jüttner <nick.juettner@zalando.de>
|
141
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/README.md
generated
vendored
Normal file
141
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/README.md
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
# Gin-Glog
|
||||||
|
|
||||||
|
[Gin](https://github.com/gin-gonic/gin) middleware for Logging with
|
||||||
|
[glog](https://github.com/golang/glog). It is meant as drop in
|
||||||
|
replacement for the default logger used in Gin.
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/zalando-techmonkeys/gin-glog.svg?branch=master)](https://travis-ci.org/zalando-techmonkeys/gin-glog)
|
||||||
|
[![Coverage Status](https://coveralls.io/repos/zalando-techmonkeys/gin-glog/badge.svg?branch=master&service=github)](https://coveralls.io/github/zalando-techmonkeys/gin-glog?branch=master)
|
||||||
|
[![Go Report Card](http://goreportcard.com/badge/zalando-techmonkeys/gin-glog)](http://goreportcard.com/report/zalando-techmonkeys/gin-glog)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/zalando-techmonkeys/gin-glog?status.svg)](http://godoc.org/github.com/zalando-techmonkeys/gin-glog)
|
||||||
|
|
||||||
|
## Project Context and Features
|
||||||
|
|
||||||
|
When it comes to choosing a Go framework, there's a lot of confusion
|
||||||
|
about what to use. The scene is very fragmented, and detailed
|
||||||
|
comparisons of different frameworks are still somewhat rare. Meantime,
|
||||||
|
how to handle dependencies and structure projects are big topics in
|
||||||
|
the Golang community. We've liked using Gin for its speed,
|
||||||
|
accessibility, and usefulness in developing microservice
|
||||||
|
architectures. In creating Gin-Glog, we wanted to take fuller
|
||||||
|
advantage of [Gin](https://github.com/gin-gonic/gin)'s capabilities
|
||||||
|
and help other devs do likewise.
|
||||||
|
|
||||||
|
Gin-Glog replaces the default logger of [Gin](https://github.com/gin-gonic/gin) to use
|
||||||
|
[Glog](https://github.com/golang/glog).
|
||||||
|
|
||||||
|
## How Glog is different compared to other loggers
|
||||||
|
|
||||||
|
Glog is an efficient pure Go implementation of leveled logs. If you
|
||||||
|
use Glog, you do not use blocking calls for writing logs. A goroutine
|
||||||
|
in the background will flush queued loglines into appropriate
|
||||||
|
logfiles. It provides logrotation, maintains symlinks to current files
|
||||||
|
and creates flags to your command line interface.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Gin-Glog uses the following [Go](https://golang.org/) packages as
|
||||||
|
dependencies:
|
||||||
|
|
||||||
|
- github.com/gin-gonic/gin
|
||||||
|
- github.com/golang/glog
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Assuming you've installed Go and Gin, run this:
|
||||||
|
|
||||||
|
go get github.com/zalando-techmonkeys/gin-glog
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
### Example
|
||||||
|
|
||||||
|
Start your webapp to log to STDERR and /tmp:
|
||||||
|
|
||||||
|
% ./webapp -log_dir="/tmp" -alsologtostderr -v=2
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/zalando-techmonkeys/gin-glog"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
router := gin.New()
|
||||||
|
router.Use(ginglog.Logger(3 * time.Second))
|
||||||
|
//..
|
||||||
|
router.Use(gin.Recovery())
|
||||||
|
|
||||||
|
glog.Warning("warning")
|
||||||
|
glog.Error("err")
|
||||||
|
glog.Info("info")
|
||||||
|
glog.V(2).Infoln("This line will be printed if you use -v=N with N >= 2.")
|
||||||
|
|
||||||
|
router.Run(":8080")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
STDERR output of the example above. Lines with prefix "[Gin-Debug]"
|
||||||
|
are hardcoded output of Gin and will not appear in your logfile:
|
||||||
|
|
||||||
|
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||||
|
- using env: export GIN_MODE=release
|
||||||
|
- using code: gin.SetMode(gin.ReleaseMode)
|
||||||
|
|
||||||
|
W0306 16:37:12.836001 367 main.go:18] warning
|
||||||
|
E0306 16:37:12.836335 367 main.go:19] err
|
||||||
|
I0306 16:37:12.836402 367 main.go:20] info
|
||||||
|
I0306 16:26:33.901278 32538 main.go:19] This line will be printed if you use -v=N with N >= 2.
|
||||||
|
[GIN-debug] Listening and serving HTTP on :8080
|
||||||
|
|
||||||
|
|
||||||
|
## Synopsis
|
||||||
|
|
||||||
|
Glog will add the following flags to your binary:
|
||||||
|
|
||||||
|
-alsologtostderr
|
||||||
|
log to standard error as well as files
|
||||||
|
-log_backtrace_at value
|
||||||
|
when logging hits line file:N, emit a stack trace (default :0)
|
||||||
|
-log_dir string
|
||||||
|
If non-empty, write log files in this directory
|
||||||
|
-logtostderr
|
||||||
|
log to standard error instead of files
|
||||||
|
-stderrthreshold value
|
||||||
|
logs at or above this threshold go to stderr
|
||||||
|
-v value
|
||||||
|
log level for V logs
|
||||||
|
-vmodule value
|
||||||
|
comma-separated list of pattern=N settings for file-filtered logging
|
||||||
|
|
||||||
|
|
||||||
|
## Contributing/TODO
|
||||||
|
|
||||||
|
We welcome contributions from the community; just submit a pull
|
||||||
|
request. To help you get started, here are some items that we'd love
|
||||||
|
help with:
|
||||||
|
|
||||||
|
- Remove hardcoded logs in [Gin](https://github.com/gin-gonic/gin)
|
||||||
|
- the code base
|
||||||
|
|
||||||
|
If you need to:
|
||||||
|
|
||||||
|
* create an issue: please create them on github
|
||||||
|
* get in contact: team-techmonkeys@zalando.de
|
||||||
|
* a list of [MAINTAINERS](MAINTAINERS)
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
Thanks to:
|
||||||
|
|
||||||
|
- <your name>
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE) file.
|
168
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/ginglog.go
generated
vendored
Normal file
168
Godeps/_workspace/src/github.com/zalando-techmonkeys/gin-glog/ginglog.go
generated
vendored
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
// Package ginglog provides a logging middleware to get
|
||||||
|
// https://github.com/golang/glog as logging library for
|
||||||
|
// https://github.com/gin-gonic/gin. It can be used as replacement for
|
||||||
|
// the internal logging middleware
|
||||||
|
// http://godoc.org/github.com/gin-gonic/gin#Logger.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// package main
|
||||||
|
// import (
|
||||||
|
// "flag
|
||||||
|
// "time"
|
||||||
|
// "github.com/golang/glog"
|
||||||
|
// "github.com/zalando-techmonkeys/gin-glog"
|
||||||
|
// "github.com/gin-gonic/gin"
|
||||||
|
// )
|
||||||
|
// func main() {
|
||||||
|
// flag.Parse()
|
||||||
|
// router := gin.New()
|
||||||
|
// router.Use(ginglog.Logger(3 * time.Second))
|
||||||
|
// //..
|
||||||
|
// router.Use(gin.Recovery())
|
||||||
|
// glog.Info("bootstrapped application")
|
||||||
|
// router.Run(":8080")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Your service will get new command line parameters from
|
||||||
|
// https://github.com/golang/glog.
|
||||||
|
package ginglog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/golang/glog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupLogging(duration time.Duration) {
|
||||||
|
go func() {
|
||||||
|
for range time.Tick(duration) {
|
||||||
|
glog.Flush()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
|
||||||
|
white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
|
||||||
|
yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
|
||||||
|
red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
|
||||||
|
blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
|
||||||
|
magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
|
||||||
|
cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
|
||||||
|
reset = string([]byte{27, 91, 48, 109})
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrorLogger returns an ErrorLoggerT with parameter gin.ErrorTypeAny
|
||||||
|
func ErrorLogger() gin.HandlerFunc {
|
||||||
|
return ErrorLoggerT(gin.ErrorTypeAny)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorLoggerT returns an ErrorLoggerT middleware with the given
|
||||||
|
// type gin.ErrorType.
|
||||||
|
func ErrorLoggerT(typ gin.ErrorType) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Next()
|
||||||
|
|
||||||
|
if !c.Writer.Written() {
|
||||||
|
json := c.Errors.ByType(typ).JSON()
|
||||||
|
if json != nil {
|
||||||
|
c.JSON(-1, json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger prints a logline for each request and measures the time to
|
||||||
|
// process for a call. It formats the log entries similar to
|
||||||
|
// http://godoc.org/github.com/gin-gonic/gin#Logger does.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// router := gin.New()
|
||||||
|
// router.Use(ginglog.Logger(3 * time.Second))
|
||||||
|
func Logger(duration time.Duration) gin.HandlerFunc {
|
||||||
|
setupLogging(duration)
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
t := time.Now()
|
||||||
|
|
||||||
|
// process request
|
||||||
|
c.Next()
|
||||||
|
|
||||||
|
latency := time.Since(t)
|
||||||
|
clientIP := c.ClientIP()
|
||||||
|
method := c.Request.Method
|
||||||
|
statusCode := c.Writer.Status()
|
||||||
|
statusColor := colorForStatus(statusCode)
|
||||||
|
methodColor := colorForMethod(method)
|
||||||
|
path := c.Request.URL.Path
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case statusCode >= 400 && statusCode <= 499:
|
||||||
|
{
|
||||||
|
glog.Warningf("[GIN] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
|
||||||
|
statusColor, statusCode, reset,
|
||||||
|
latency,
|
||||||
|
clientIP,
|
||||||
|
methodColor, reset, method,
|
||||||
|
path,
|
||||||
|
c.Errors.String(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case statusCode >= 500:
|
||||||
|
{
|
||||||
|
glog.Errorf("[GIN] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
|
||||||
|
statusColor, statusCode, reset,
|
||||||
|
latency,
|
||||||
|
clientIP,
|
||||||
|
methodColor, reset, method,
|
||||||
|
path,
|
||||||
|
c.Errors.String(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
glog.V(2).Infof("[GIN] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
|
||||||
|
statusColor, statusCode, reset,
|
||||||
|
latency,
|
||||||
|
clientIP,
|
||||||
|
methodColor, reset, method,
|
||||||
|
path,
|
||||||
|
c.Errors.String(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func colorForStatus(code int) string {
|
||||||
|
switch {
|
||||||
|
case code >= 200 && code <= 299:
|
||||||
|
return green
|
||||||
|
case code >= 300 && code <= 399:
|
||||||
|
return white
|
||||||
|
case code >= 400 && code <= 499:
|
||||||
|
return yellow
|
||||||
|
default:
|
||||||
|
return red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func colorForMethod(method string) string {
|
||||||
|
switch {
|
||||||
|
case method == "GET":
|
||||||
|
return blue
|
||||||
|
case method == "POST":
|
||||||
|
return cyan
|
||||||
|
case method == "PUT":
|
||||||
|
return yellow
|
||||||
|
case method == "DELETE":
|
||||||
|
return red
|
||||||
|
case method == "PATCH":
|
||||||
|
return green
|
||||||
|
case method == "HEAD":
|
||||||
|
return magenta
|
||||||
|
case method == "OPTIONS":
|
||||||
|
return white
|
||||||
|
default:
|
||||||
|
return reset
|
||||||
|
}
|
||||||
|
}
|
7
Makefile
7
Makefile
|
@ -6,7 +6,7 @@ CUR_DIR=$(shell pwd)
|
||||||
GOPATH=$(CUR_DIR)/build/
|
GOPATH=$(CUR_DIR)/build/
|
||||||
|
|
||||||
PARENT_PKG=amuz.es/go/
|
PARENT_PKG=amuz.es/go/
|
||||||
NAME=wiki
|
NAME=mnemonics
|
||||||
PKG=$(PARENT_PKG)$(NAME)
|
PKG=$(PARENT_PKG)$(NAME)
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
|
@ -34,7 +34,7 @@ test-all:
|
||||||
|
|
||||||
assets-%: asset/%/
|
assets-%: asset/%/
|
||||||
@echo "serialize $*"
|
@echo "serialize $*"
|
||||||
@go-bindata -o bind/$*/handler.go -pkg $* -prefix $* -ignore=[.]gitignore -ignore=[.]gitkeep -prefix asset/$*/ $(BINDATA_OPTS) $<...
|
@$(GOPATH)bin/go-bindata -o bind/$*/handler.go -pkg $* -prefix $* -ignore=[.]gitignore -ignore=[.]gitkeep -prefix asset/$*/ $(BINDATA_OPTS) $<...
|
||||||
|
|
||||||
assets: $(addprefix assets-,${ASSETS})
|
assets: $(addprefix assets-,${ASSETS})
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ dependency-restore:
|
||||||
godep restore
|
godep restore
|
||||||
|
|
||||||
|
|
||||||
build: setup assets
|
build: assets
|
||||||
godep go build
|
godep go build
|
||||||
@echo "You can now execute ./$(NAME)"
|
@echo "You can now execute ./$(NAME)"
|
||||||
|
|
||||||
|
@ -77,3 +77,4 @@ clean:
|
||||||
rm -f ./$(NAME)
|
rm -f ./$(NAME)
|
||||||
rm -rf ./build
|
rm -rf ./build
|
||||||
rm -rf ./bind/*
|
rm -rf ./bind/*
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/zalando-techmonkeys/gin-glog"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"time"
|
||||||
"flag"
|
"flag"
|
||||||
"amuz.es/go/wiki/route"
|
"amuz.es/go/mnemonics/route"
|
||||||
"amuz.es/go/wiki/util"
|
"amuz.es/go/mnemonics/util"
|
||||||
"net/http"
|
"net/http"
|
||||||
"github.com/flosch/pongo2"
|
"github.com/flosch/pongo2"
|
||||||
)
|
)
|
||||||
|
@ -30,9 +32,12 @@ var argPort = flag.Int("port", 8080, "port to listen")
|
||||||
var maxProcs = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).")
|
var maxProcs = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).")
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
setMaxProcs()
|
setMaxProcs()
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
|
r.Use(ginglog.Logger(3 * time.Second))
|
||||||
|
|
||||||
r.Use(gin.Recovery())
|
r.Use(gin.Recovery())
|
||||||
|
|
||||||
r.NoRoute(func(c *gin.Context) {
|
r.NoRoute(func(c *gin.Context) {
|
||||||
|
@ -45,13 +50,16 @@ func main() {
|
||||||
r.GET("/page", route.Page)
|
r.GET("/page", route.Page)
|
||||||
r.GET("/metric", route.Metric)
|
r.GET("/metric", route.Metric)
|
||||||
r.GET("/health", func(c *gin.Context) {
|
r.GET("/health", func(c *gin.Context) {
|
||||||
c.String(200, "OK! - wiki services are fully operational!")
|
c.String(200, "OK! - mnemonics services are fully operational!")
|
||||||
})
|
})
|
||||||
|
|
||||||
// Use pongo2gin.Default() for default options or pongo2gin.New()
|
// Use pongo2gin.Default() for default options or pongo2gin.New()
|
||||||
// if you need to use custom RenderOptions.
|
// if you need to use custom RenderOptions.
|
||||||
r.HTMLRender = util.Default()
|
r.HTMLRender = util.Default()
|
||||||
r.GET("/", route.Index)
|
r.GET("/", route.Index)
|
||||||
|
|
||||||
|
|
||||||
|
glog.Info("bootstrapped application")
|
||||||
r.Run() // listen and server on 0.0.0.0:8080
|
r.Run() // listen and server on 0.0.0.0:8080
|
||||||
}
|
}
|
||||||
|
|
147
route/metric.go
147
route/metric.go
|
@ -4,132 +4,57 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
"amuz.es/go/wiki/util"
|
"amuz.es/go/mnemonics/util"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Metric(c *gin.Context) {
|
|
||||||
updateSystemStatus()
|
|
||||||
metricInfo:=sysStatus
|
|
||||||
content := gin.H{
|
|
||||||
"uptime":metricInfo.Uptime,
|
|
||||||
"numGoroutine":metricInfo.NumGoroutine,
|
|
||||||
|
|
||||||
"memAllocated":metricInfo.MemAllocated,
|
|
||||||
"memTotal":metricInfo.MemTotal,
|
|
||||||
"memSys":metricInfo.MemSys,
|
|
||||||
"lookups":metricInfo.Lookups,
|
|
||||||
"memMallocs":metricInfo.MemMallocs,
|
|
||||||
"memFrees":metricInfo.MemFrees,
|
|
||||||
|
|
||||||
"heapAlloc":metricInfo.HeapAlloc,
|
|
||||||
"heapSys":metricInfo.HeapSys,
|
|
||||||
"heapIdle":metricInfo.HeapIdle,
|
|
||||||
"heapInuse":metricInfo.HeapInuse,
|
|
||||||
"heapReleased":metricInfo.HeapReleased,
|
|
||||||
"heapObjects":metricInfo.HeapObjects,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"stackInuse":metricInfo.StackInuse,
|
|
||||||
"stackSys":metricInfo.StackSys,
|
|
||||||
"mSpanInuse":metricInfo.MSpanInuse,
|
|
||||||
"mSpanSys":metricInfo.MSpanSys,
|
|
||||||
"mCacheInuse":metricInfo.MCacheInuse,
|
|
||||||
"mCacheSys":metricInfo.MCacheSys,
|
|
||||||
"buckHashSys":metricInfo.BuckHashSys,
|
|
||||||
"gCSys":metricInfo.GCSys,
|
|
||||||
"otherSys":metricInfo.OtherSys,
|
|
||||||
|
|
||||||
"nextGC":metricInfo.NextGC,
|
|
||||||
"lastGC":metricInfo.LastGC,
|
|
||||||
"pauseTotalNs":metricInfo.PauseTotalNs,
|
|
||||||
"pauseNs":metricInfo.PauseNs,
|
|
||||||
"numGC":metricInfo.NumGC}
|
|
||||||
c.JSON(200, content)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
)
|
)
|
||||||
|
|
||||||
var sysStatus struct {
|
|
||||||
Uptime string
|
|
||||||
NumGoroutine int
|
|
||||||
|
|
||||||
// General statistics.
|
func Metric(c *gin.Context) {
|
||||||
MemAllocated string // bytes allocated and still in use
|
memory:=serializeMemoryStat()
|
||||||
MemTotal string // bytes allocated (even if freed)
|
content := gin.H{"memory":memory}
|
||||||
MemSys string // bytes obtained from system (sum of XxxSys below)
|
c.JSON(200, content)
|
||||||
Lookups uint64 // number of pointer lookups
|
|
||||||
MemMallocs uint64 // number of mallocs
|
|
||||||
MemFrees uint64 // number of frees
|
|
||||||
|
|
||||||
// Main allocation heap statistics.
|
|
||||||
HeapAlloc string // bytes allocated and still in use
|
|
||||||
HeapSys string // bytes obtained from system
|
|
||||||
HeapIdle string // bytes in idle spans
|
|
||||||
HeapInuse string // bytes in non-idle span
|
|
||||||
HeapReleased string // bytes released to the OS
|
|
||||||
HeapObjects uint64 // total number of allocated objects
|
|
||||||
|
|
||||||
// Low-level fixed-size structure allocator statistics.
|
|
||||||
// Inuse is bytes used now.
|
|
||||||
// Sys is bytes obtained from system.
|
|
||||||
StackInuse string // bootstrap stacks
|
|
||||||
StackSys string
|
|
||||||
MSpanInuse string // mspan structures
|
|
||||||
MSpanSys string
|
|
||||||
MCacheInuse string // mcache structures
|
|
||||||
MCacheSys string
|
|
||||||
BuckHashSys string // profiling bucket hash table
|
|
||||||
GCSys string // GC metadata
|
|
||||||
OtherSys string // other system allocations
|
|
||||||
|
|
||||||
// Garbage collector statistics.
|
|
||||||
NextGC string // next run in HeapAlloc time (bytes)
|
|
||||||
LastGC string // last run in absolute time (ns)
|
|
||||||
PauseTotalNs string
|
|
||||||
PauseNs string // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
|
|
||||||
NumGC uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSystemStatus() {
|
func serializeMemoryStat() map[string]interface{} {
|
||||||
sysStatus.Uptime = util.TimeSincePro(startTime)
|
|
||||||
|
|
||||||
m := new(runtime.MemStats)
|
m := new(runtime.MemStats)
|
||||||
runtime.ReadMemStats(m)
|
runtime.ReadMemStats(m)
|
||||||
sysStatus.NumGoroutine = runtime.NumGoroutine()
|
return gin.H{
|
||||||
|
"uptime":util.TimeSincePro(startTime),
|
||||||
|
"numGoroutine":runtime.NumGoroutine(),
|
||||||
|
|
||||||
sysStatus.MemAllocated = util.FileSize(int64(m.Alloc))
|
"memAllocated":util.FileSize(int64(m.Alloc)),
|
||||||
sysStatus.MemTotal = util.FileSize(int64(m.TotalAlloc))
|
"memTotal":util.FileSize(int64(m.TotalAlloc)),
|
||||||
sysStatus.MemSys = util.FileSize(int64(m.Sys))
|
"memSys":util.FileSize(int64(m.Sys)),
|
||||||
sysStatus.Lookups = m.Lookups
|
"lookups":m.Lookups,
|
||||||
sysStatus.MemMallocs = m.Mallocs
|
"memMallocs":m.Mallocs,
|
||||||
sysStatus.MemFrees = m.Frees
|
"memFrees":m.Frees,
|
||||||
|
|
||||||
sysStatus.HeapAlloc = util.FileSize(int64(m.HeapAlloc))
|
"heapAlloc":util.FileSize(int64(m.HeapAlloc)),
|
||||||
sysStatus.HeapSys = util.FileSize(int64(m.HeapSys))
|
"heapSys":util.FileSize(int64(m.HeapSys)),
|
||||||
sysStatus.HeapIdle = util.FileSize(int64(m.HeapIdle))
|
"heapIdle":util.FileSize(int64(m.HeapIdle)),
|
||||||
sysStatus.HeapInuse = util.FileSize(int64(m.HeapInuse))
|
"heapInuse":util.FileSize(int64(m.HeapInuse)),
|
||||||
sysStatus.HeapReleased = util.FileSize(int64(m.HeapReleased))
|
"heapReleased":util.FileSize(int64(m.HeapReleased)),
|
||||||
sysStatus.HeapObjects = m.HeapObjects
|
"heapObjects":m.HeapObjects,
|
||||||
|
|
||||||
sysStatus.StackInuse = util.FileSize(int64(m.StackInuse))
|
|
||||||
sysStatus.StackSys = util.FileSize(int64(m.StackSys))
|
|
||||||
sysStatus.MSpanInuse = util.FileSize(int64(m.MSpanInuse))
|
|
||||||
sysStatus.MSpanSys = util.FileSize(int64(m.MSpanSys))
|
|
||||||
sysStatus.MCacheInuse = util.FileSize(int64(m.MCacheInuse))
|
|
||||||
sysStatus.MCacheSys = util.FileSize(int64(m.MCacheSys))
|
|
||||||
sysStatus.BuckHashSys = util.FileSize(int64(m.BuckHashSys))
|
|
||||||
sysStatus.GCSys = util.FileSize(int64(m.GCSys))
|
|
||||||
sysStatus.OtherSys = util.FileSize(int64(m.OtherSys))
|
|
||||||
|
|
||||||
sysStatus.NextGC = util.FileSize(int64(m.NextGC))
|
"stackInuse":util.FileSize(int64(m.StackInuse)),
|
||||||
sysStatus.LastGC = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000)
|
"stackSys":util.FileSize(int64(m.StackSys)),
|
||||||
sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs)/1000/1000/1000)
|
"mSpanInuse":util.FileSize(int64(m.MSpanInuse)),
|
||||||
sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256])/1000/1000/1000)
|
"mSpanSys":util.FileSize(int64(m.MSpanSys)),
|
||||||
sysStatus.NumGC = m.NumGC
|
"mCacheInuse":util.FileSize(int64(m.MCacheInuse)),
|
||||||
|
"mCacheSys":util.FileSize(int64(m.MCacheSys)),
|
||||||
|
"buckHashSys":util.FileSize(int64(m.BuckHashSys)),
|
||||||
|
"gCSys":util.FileSize(int64(m.GCSys)),
|
||||||
|
"otherSys":util.FileSize(int64(m.OtherSys)),
|
||||||
|
|
||||||
|
"nextGC":util.FileSize(int64(m.NextGC)),
|
||||||
|
"lastGC":fmt.Sprintf("%.1fs", float64(time.Now().UnixNano() - int64(m.LastGC)) / 1000 / 1000 / 1000),
|
||||||
|
"pauseTotalNs":fmt.Sprintf("%.1fs", float64(m.PauseTotalNs) / 1000 / 1000 / 1000),
|
||||||
|
"pauseNs":fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC + 255) % 256]) / 1000 / 1000 / 1000),
|
||||||
|
"numGC":m.NumGC}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||||
"amuz.es/go/wiki/bind/static"
|
"amuz.es/go/mnemonics/bind/static"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,7 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"amuz.es/go/wiki/bind/template"
|
"amuz.es/go/mnemonics/bind/template"
|
||||||
"github.com/flosch/pongo2"
|
"github.com/flosch/pongo2"
|
||||||
"github.com/gin-gonic/gin/render"
|
"github.com/gin-gonic/gin/render"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue