github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/runtime/runtime.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package runtime
    18  
    19  import (
    20  	"fmt"
    21  	"github.com/golang/glog"
    22  	"runtime"
    23  )
    24  
    25  // For testing, bypass HandleCrash.
    26  var ReallyCrash bool
    27  
    28  // PanicHandlers is a list of functions which will be invoked when a panic happens.
    29  var PanicHandlers = []func(interface{}){logPanic}
    30  
    31  //TODO search the public functions
    32  // HandleCrash simply catches a crash and logs an error. Meant to be called via defer.
    33  // Additional context-specific handlers can be provided, and will be called in case of panic
    34  func HandleCrash(additionalHandlers ...func(interface{})) {
    35  	if ReallyCrash {
    36  		return
    37  	}
    38  	if r := recover(); r != nil {
    39  		for _, fn := range PanicHandlers {
    40  			fn(r)
    41  		}
    42  		for _, fn := range additionalHandlers {
    43  			fn(r)
    44  		}
    45  	}
    46  }
    47  
    48  // logPanic logs the caller tree when a panic occurs.
    49  func logPanic(r interface{}) {
    50  	callers := ""
    51  	for i := 0; true; i++ {
    52  		_, file, line, ok := runtime.Caller(i)
    53  		if !ok {
    54  			break
    55  		}
    56  		callers = callers + fmt.Sprintf("%v:%v\n", file, line)
    57  	}
    58  	glog.Errorf("Recovered from panic: %#v (%v)\n%v", r, r, callers)
    59  }
    60  
    61  // ErrorHandlers is a list of functions which will be invoked when an unreturnable
    62  // error occurs.
    63  var ErrorHandlers = []func(error){logError}
    64  
    65  // HandlerError is a method to invoke when a non-user facing piece of code cannot
    66  // return an error and needs to indicate it has been ignored. Invoking this method
    67  // is preferable to logging the error - the default behavior is to log but the
    68  // errors may be sent to a remote server for analysis.
    69  func HandleError(err error) {
    70  	// this is sometimes called with a nil error.  We probably shouldn't fail and should do nothing instead
    71  	if err == nil {
    72  		return
    73  	}
    74  
    75  	for _, fn := range ErrorHandlers {
    76  		fn(err)
    77  	}
    78  }
    79  
    80  // logError prints an error with the call stack of the location it was reported
    81  func logError(err error) {
    82  	glog.ErrorDepth(2, err)
    83  }
    84  
    85  // GetCaller returns the caller of the function that calls it.
    86  func GetCaller() string {
    87  	var pc [1]uintptr
    88  	runtime.Callers(3, pc[:])
    89  	f := runtime.FuncForPC(pc[0])
    90  	if f == nil {
    91  		return fmt.Sprintf("Unable to find caller")
    92  	}
    93  	return f.Name()
    94  }