github.com/mmatczuk/gohan@v0.0.0-20170206152520-30e45d9bdb69/extension/otto/gohan_logging.go (about) 1 // Copyright (C) 2016 NTT Innovation Institute, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package otto 17 18 import ( 19 "github.com/robertkrimen/otto" 20 //Import otto underscore lib 21 _ "github.com/robertkrimen/otto/underscore" 22 23 l "github.com/cloudwan/gohan/log" 24 ) 25 26 const ( 27 // e.g. {Log level} must be {an int}: "ERROR" 28 wrongTypeErrorMessageFormat = "%s must be %s: %v" 29 ) 30 31 func init() { 32 gohanLoggingInit := func(env *Environment) { 33 vm := env.VM 34 35 builtins := map[string]interface{}{ 36 "gohan_log": func(call otto.FunctionCall) otto.Value { 37 VerifyCallArguments(&call, "gohan_log", 3) 38 39 // TODO: 40 // Taking this as an argument is a workaround 41 // for Otto returning stale values of variables 42 // that have been changed in javascript. 43 // We can get this from LOG_MODULE javascript 44 // variable if we fix the problem. 45 module, err := GetString(call.Argument(0)) 46 if err != nil { 47 ThrowOttoException(&call, "Log module: %v", err) 48 } 49 logger := l.NewLoggerForModule(module) 50 51 intLevel, err := GetInt64(call.Argument(1)) 52 if err != nil { 53 ThrowOttoException(&call, "Log level: %v", err) 54 } 55 level := l.Level(intLevel) 56 57 message, err := GetString(call.Argument(2)) 58 if err != nil { 59 ThrowOttoException(&call, "Message: %v", err) 60 } 61 62 logGeneral(logger, level, message) 63 64 return otto.Value{} 65 }, 66 } 67 for name, object := range builtins { 68 vm.Set(name, object) 69 } 70 71 // op/go-logging/level.go has levelNames[], but it's unexported 72 logLevels := map[string]l.Level{ 73 "CRITICAL": l.CRITICAL, 74 "ERROR": l.ERROR, 75 "WARNING": l.WARNING, 76 "NOTICE": l.NOTICE, 77 "INFO": l.INFO, 78 "DEBUG": l.DEBUG, 79 } 80 vm.Set("LOG_LEVEL", logLevels) 81 82 vm.Set("LOG_MODULE", "gohan.extension."+env.Name) 83 84 err := env.Load("<Gohan logging built-ins>", ` 85 function gohan_log_module_push(new_module){ 86 var old_module = LOG_MODULE; 87 LOG_MODULE += "." + new_module; 88 return old_module; 89 } 90 91 function gohan_log_module_restore(old_module){ 92 LOG_MODULE = old_module; 93 } 94 95 function gohan_log_critical(msg) { 96 gohan_log(LOG_MODULE, LOG_LEVEL.CRITICAL, msg); 97 } 98 99 function gohan_log_error(msg) { 100 gohan_log(LOG_MODULE, LOG_LEVEL.ERROR, msg); 101 } 102 103 function gohan_log_warning(msg) { 104 gohan_log(LOG_MODULE, LOG_LEVEL.WARNING, msg); 105 } 106 107 function gohan_log_notice(msg) { 108 gohan_log(LOG_MODULE, LOG_LEVEL.NOTICE, msg); 109 } 110 111 function gohan_log_info(msg) { 112 gohan_log(LOG_MODULE, LOG_LEVEL.INFO, msg); 113 } 114 115 function gohan_log_debug(msg) { 116 gohan_log(LOG_MODULE, LOG_LEVEL.DEBUG, msg); 117 } 118 `) 119 if err != nil { 120 log.Fatal(err) 121 } 122 } 123 RegisterInit(gohanLoggingInit) 124 } 125 126 // logGeneral can be replaced with logger.Log(level, format, args) when https://github.com/op/go-logging/issues/80 gets fixed. 127 func logGeneral(logger l.Logger, level l.Level, format string, args ...interface{}) { 128 var logAction func(format string, args ...interface{}) 129 switch level { 130 case l.CRITICAL: 131 logAction = logger.Critical 132 case l.ERROR: 133 logAction = logger.Error 134 case l.WARNING: 135 logAction = logger.Warning 136 case l.NOTICE: 137 logAction = logger.Notice 138 case l.INFO: 139 logAction = logger.Info 140 case l.DEBUG: 141 logAction = logger.Debug 142 } 143 144 logAction(format, args...) 145 } 146 147 // PushJSLogModule appends newModule to log module in env, returns a function that restores the original value 148 func PushJSLogModule(env *Environment, newModule string) (restore func()) { 149 newModuleInVM, _ := env.VM.ToValue(newModule) 150 oldModule := pushJSLogModule(env, newModuleInVM) 151 return func() { 152 restoreJSLogModule(env, oldModule) 153 } 154 } 155 156 func restoreJSLogModule(env *Environment, oldModule otto.Value) { 157 _, err := env.VM.Call("gohan_log_module_restore", nil, oldModule) 158 if err != nil { 159 log.Error("Calling gohan_log_module_restore: " + err.Error()) 160 } 161 } 162 163 func pushJSLogModule(env *Environment, newModule otto.Value) (oldModule otto.Value) { 164 oldModule, err := env.VM.Call("gohan_log_module_push", nil, newModule) 165 if err != nil { 166 log.Error("Calling gohan_log_module_push: " + err.Error()) 167 } 168 return 169 }