Пример #1
0
// NewContext creates a new context that is watching a live task. See Start
// or MonitorGroup.Task
func (t *TaskMonitor) NewContext() *TaskCtx {
	t.mtx.Lock()
	t.current += 1
	t.total_started += 1
	if t.current > t.highwater {
		t.highwater = t.current
	}
	t.mtx.Unlock()
	return &TaskCtx{start: monotime.Monotonic(), monitor: t}
}
Пример #2
0
// RegisterEnvironment configures the MonitorStore receiver to understand all
// sorts of process environment statistics, such as memory statistics,
// process uptime, file descriptor use, goroutine use, runtime internals,
// Rusage stats, etc.
func (store *MonitorStore) RegisterEnvironment() {
	if store == nil {
		store = DefaultStore
	}
	group := store.GetMonitorsNamed("env")

	group.Chain("goroutines", MonitorFunc(
		func(cb func(name string, val float64)) {
			cb("count", float64(runtime.NumGoroutine()))
		}))

	group.Chain("memory", MonitorFunc(
		func(cb func(name string, val float64)) {
			var stats runtime.MemStats
			runtime.ReadMemStats(&stats)
			MonitorStruct(stats, cb)
		}))

	process_crc, err := ProcessCRC()
	if err != nil {
		logger.Errorf("failed determining process crc: %s", err)
		process_crc = 0
	}

	group.Chain("process", MonitorFunc(
		func(cb func(name string, val float64)) {
			cb("control", 1)
			fds, err := FdCount()
			if err != nil {
				logger.Errorf("failed getting fd count: %s", err)
			} else {
				cb("fds", float64(fds))
			}
			cb("crc", float64(process_crc))
			cb("uptime", (monotime.Monotonic() - startTime).Seconds())
		}))

	group.Chain("runtime", MonitorFunc(
		func(cb func(name string, val float64)) {
			MonitorStruct(RuntimeInternals(), cb)
		}))

	group.Chain("rusage", MonitorFunc(
		func(cb func(name string, val float64)) {
			var rusage syscall.Rusage
			err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage)
			if err != nil {
				logger.Errorf("failed getting rusage data: %s", err)
				return
			}
			MonitorStruct(&rusage, cb)
		}))
}
Пример #3
0
// Finish records a successful task completion. You must pass a pointer to
// the named error return value (or nil if there isn't one) and the result
// of recover() out of the method that was deferred for this to work right.
// Finish will re-panic any recovered panics (provided it wasn't a nil panic)
// after bookkeeping.
func (c *TaskCtx) Finish(err_ref *error, rec interface{}) {
	duration_nanoseconds := int64(monotime.Monotonic() - c.start)
	var error_name string
	var err error
	if err_ref != nil {
		err = *err_ref
	}
	if rec != nil {
		var ok bool
		err, ok = rec.(error)
		if !ok || err == nil {
			err = errors.PanicError.New("%v", rec)
		}
	}
	if err != nil {
		error_name = errors.GetClass(err).String()
		max_len := Config.MaxErrorLength
		if len(error_name) > max_len {
			error_name = error_name[:max_len]
		}
		error_name = SanitizeName(error_name)
	}

	// we keep granularity on the order microseconds, which should keep
	// sum_squared useful
	duration_microseconds := int64(duration_nanoseconds /
		microsecondInNanoseconds)

	c.monitor.mtx.Lock()
	c.monitor.current -= 1
	c.monitor.total_completed += 1
	if err != nil {
		c.monitor.errors[error_name] += 1
		if rec != nil {
			c.monitor.panics += 1
		}
		c.monitor.error_timing.Add(duration_microseconds)
	} else {
		c.monitor.success_timing.Add(duration_microseconds)
		c.monitor.success += 1
	}
	c.monitor.mtx.Unlock()
	c.monitor.total_timing.Add(duration_microseconds)

	// doh, we didn't actually want to stop the panic codepath.
	// we have to repanic. Oh and great, panics can be nil. Welp!
	if rec != nil {
		panic(rec)
	}
}
Пример #4
0
package monitor

import (
	"fmt"
	"io"
	"os"
	"runtime"
	"syscall"

	"github.com/spacemonkeygo/crc"
	"github.com/spacemonkeygo/monotime"
)

var (
	startTime = monotime.Monotonic()
)

// RegisterEnvironment configures the MonitorStore receiver to understand all
// sorts of process environment statistics, such as memory statistics,
// process uptime, file descriptor use, goroutine use, runtime internals,
// Rusage stats, etc.
func (store *MonitorStore) RegisterEnvironment() {
	if store == nil {
		store = DefaultStore
	}
	group := store.GetMonitorsNamed("env")

	group.Chain("goroutines", MonitorFunc(
		func(cb func(name string, val float64)) {
			cb("count", float64(runtime.NumGoroutine()))
Пример #5
0
func nowTimestamp() uint32 {
	return uint32(monotime.Monotonic() / time.Microsecond)
}
Пример #6
0
// Elapsed just returns the amount of time since the timer started
func (r *RunningTimer) Elapsed() time.Duration {
	return monotime.Monotonic() - r.start
}
Пример #7
0
// Start constructs a RunningTimer
func (t *Timer) Start() *RunningTimer {
	return &RunningTimer{
		start: monotime.Monotonic(),
		t:     t}
}
Пример #8
0
func (t TaskCtx) ElapsedTime() time.Duration {
	return monotime.Monotonic() - t.start
}