mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	
		
			
				
	
	
		
			155 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2014 The Macaron Authors
 | |
| //
 | |
| // 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 toolbox is a middleware that provides health check, pprof, profile and statistic services for Macaron.
 | |
| package toolbox
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"net/http"
 | |
| 	"net/http/pprof"
 | |
| 	"path"
 | |
| 	"time"
 | |
| 
 | |
| 	"gopkg.in/macaron.v1"
 | |
| )
 | |
| 
 | |
| const _VERSION = "0.1.2"
 | |
| 
 | |
| func Version() string {
 | |
| 	return _VERSION
 | |
| }
 | |
| 
 | |
| // Toolbox represents a tool box service for Macaron instance.
 | |
| type Toolbox interface {
 | |
| 	AddHealthCheck(HealthChecker)
 | |
| 	AddHealthCheckFunc(string, HealthCheckFunc)
 | |
| 	AddStatistics(string, string, time.Duration)
 | |
| 	GetMap(io.Writer)
 | |
| 	JSON(io.Writer)
 | |
| }
 | |
| 
 | |
| type toolbox struct {
 | |
| 	*UrlMap
 | |
| 	healthCheckJobs []*healthCheck
 | |
| }
 | |
| 
 | |
| // Options represents a struct for specifying configuration options for the Toolbox middleware.
 | |
| type Options struct {
 | |
| 	// URL prefix for toolbox dashboard. Default is "/debug".
 | |
| 	URLPrefix string
 | |
| 	// URL for health check request. Default is "/healthcheck".
 | |
| 	HealthCheckURL string
 | |
| 	// Health checkers.
 | |
| 	HealthCheckers []HealthChecker
 | |
| 	// Health check functions.
 | |
| 	HealthCheckFuncs []*HealthCheckFuncDesc
 | |
| 	// URL for URL map json. Default is "/urlmap.json".
 | |
| 	URLMapPrefix string
 | |
| 	// URL prefix of pprof. Default is "/debug/pprof/".
 | |
| 	PprofURLPrefix string
 | |
| 	// URL prefix of profile. Default is "/debug/profile/".
 | |
| 	ProfileURLPrefix string
 | |
| 	// Path store profile files. Default is "profile".
 | |
| 	ProfilePath string
 | |
| }
 | |
| 
 | |
| var opt Options
 | |
| 
 | |
| func prepareOptions(options []Options) {
 | |
| 	if len(options) > 0 {
 | |
| 		opt = options[0]
 | |
| 	}
 | |
| 
 | |
| 	// Defaults.
 | |
| 	if len(opt.URLPrefix) == 0 {
 | |
| 		opt.URLPrefix = "/debug"
 | |
| 	}
 | |
| 	if len(opt.HealthCheckURL) == 0 {
 | |
| 		opt.HealthCheckURL = "/healthcheck"
 | |
| 	}
 | |
| 	if len(opt.URLMapPrefix) == 0 {
 | |
| 		opt.URLMapPrefix = "/urlmap.json"
 | |
| 	}
 | |
| 	if len(opt.PprofURLPrefix) == 0 {
 | |
| 		opt.PprofURLPrefix = "/debug/pprof/"
 | |
| 	} else if opt.PprofURLPrefix[len(opt.PprofURLPrefix)-1] != '/' {
 | |
| 		opt.PprofURLPrefix += "/"
 | |
| 	}
 | |
| 	if len(opt.ProfileURLPrefix) == 0 {
 | |
| 		opt.ProfileURLPrefix = "/debug/profile/"
 | |
| 	} else if opt.ProfileURLPrefix[len(opt.ProfileURLPrefix)-1] != '/' {
 | |
| 		opt.ProfileURLPrefix += "/"
 | |
| 	}
 | |
| 	if len(opt.ProfilePath) == 0 {
 | |
| 		opt.ProfilePath = path.Join(macaron.Root, "profile")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func dashboard(ctx *macaron.Context) string {
 | |
| 	return fmt.Sprintf(`<p>Toolbox Index:</p>
 | |
| 	<ol>
 | |
| 	    <li><a href="%s">Pprof Information</a></li>
 | |
|         <li><a href="%s">Profile Operations</a></li>
 | |
| 	</ol>`, opt.PprofURLPrefix, opt.ProfileURLPrefix)
 | |
| }
 | |
| 
 | |
| var _ Toolbox = &toolbox{}
 | |
| 
 | |
| // Toolboxer is a middleware provides health check, pprof, profile and statistic services for your application.
 | |
| func Toolboxer(m *macaron.Macaron, options ...Options) macaron.Handler {
 | |
| 	prepareOptions(options)
 | |
| 	t := &toolbox{
 | |
| 		healthCheckJobs: make([]*healthCheck, 0, len(opt.HealthCheckers)+len(opt.HealthCheckFuncs)),
 | |
| 	}
 | |
| 
 | |
| 	// Dashboard.
 | |
| 	m.Get(opt.URLPrefix, dashboard)
 | |
| 
 | |
| 	// Health check.
 | |
| 	for _, hc := range opt.HealthCheckers {
 | |
| 		t.AddHealthCheck(hc)
 | |
| 	}
 | |
| 	for _, fd := range opt.HealthCheckFuncs {
 | |
| 		t.AddHealthCheckFunc(fd.Desc, fd.Func)
 | |
| 	}
 | |
| 	m.Get(opt.HealthCheckURL, t.handleHealthCheck)
 | |
| 
 | |
| 	// URL map.
 | |
| 	m.Get(opt.URLMapPrefix, func(rw http.ResponseWriter) {
 | |
| 		t.JSON(rw)
 | |
| 	})
 | |
| 
 | |
| 	// Pprof.
 | |
| 	m.Any(path.Join(opt.PprofURLPrefix, "cmdline"), pprof.Cmdline)
 | |
| 	m.Any(path.Join(opt.PprofURLPrefix, "profile"), pprof.Profile)
 | |
| 	m.Any(path.Join(opt.PprofURLPrefix, "symbol"), pprof.Symbol)
 | |
| 	m.Any(opt.PprofURLPrefix, pprof.Index)
 | |
| 	m.Any(path.Join(opt.PprofURLPrefix, "*"), pprof.Index)
 | |
| 
 | |
| 	// Profile.
 | |
| 	profilePath = opt.ProfilePath
 | |
| 	m.Get(opt.ProfileURLPrefix, handleProfile)
 | |
| 
 | |
| 	// Routes statistic.
 | |
| 	t.UrlMap = &UrlMap{
 | |
| 		urlmap: make(map[string]map[string]*Statistics),
 | |
| 	}
 | |
| 
 | |
| 	return func(ctx *macaron.Context) {
 | |
| 		ctx.MapTo(t, (*Toolbox)(nil))
 | |
| 	}
 | |
| }
 |