mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 00:11:04 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			158 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
	
		
			4.2 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"
 | 
						|
 | 
						|
	"gitea.com/macaron/macaron"
 | 
						|
)
 | 
						|
 | 
						|
const _VERSION = "0.1.4"
 | 
						|
 | 
						|
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
 | 
						|
	// DisableDebug turns off all debug functionality.
 | 
						|
	DisableDebug bool
 | 
						|
	// 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() 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.Route(opt.HealthCheckURL, "HEAD,GET", t.handleHealthCheck)
 | 
						|
 | 
						|
	// URL map.
 | 
						|
	m.Get(opt.URLMapPrefix, func(rw http.ResponseWriter) {
 | 
						|
		t.JSON(rw)
 | 
						|
	})
 | 
						|
 | 
						|
	if !opt.DisableDebug {
 | 
						|
		// 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))
 | 
						|
	}
 | 
						|
}
 |