push code back with legal issues fix

Change-Id: I0fb323d1dedea5c1c219949684031430e7f7455e
Signed-off-by: ss412g <shuky.har-noy@intl.att.com>
diff --git a/E2Manager/logger/logger.go b/E2Manager/logger/logger.go
new file mode 100644
index 0000000..5b3232d
--- /dev/null
+++ b/E2Manager/logger/logger.go
@@ -0,0 +1,184 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// 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 logger
+
+import (
+	"fmt"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+	"strings"
+	"time"
+)
+
+type Logger struct {
+	Logger     *zap.Logger
+}
+
+// Copied from zap logger
+//
+// A Level is a logging priority. Higher levels are more important.
+type LogLevel int8
+
+const (
+	// DebugLevel logs are typically voluminous, and are usually disabled in
+	// production.
+	DebugLevel LogLevel = iota - 1
+	// InfoLevel is the default logging priority.
+	InfoLevel
+	// WarnLevel logs are more important than Info, but don't need individual
+	// human review.
+	WarnLevel
+	// ErrorLevel logs are high-priority. If an application is running smoothly,
+	// it shouldn't generate any error-level logs.
+	ErrorLevel
+	// DPanicLevel logs are particularly important errors. In development the
+	// logger panics after writing the message.
+	DPanicLevel
+	// PanicLevel logs a message, then panics.
+	PanicLevel
+	// FatalLevel logs a message, then calls os.Exit(1).
+	FatalLevel
+
+	_minLevel = DebugLevel
+	_maxLevel = FatalLevel
+)
+
+var logLevelTokenToLevel = map[string] LogLevel {
+	"debug" : DebugLevel,
+	"info": InfoLevel,
+	"warn": WarnLevel,
+	"error": ErrorLevel,
+	"dpanic": DPanicLevel,
+	"panic": PanicLevel,
+	"fatal": FatalLevel,
+}
+
+func LogLevelTokenToLevel(level string) (LogLevel, bool) {
+	if level, ok := logLevelTokenToLevel[strings.TrimSpace(strings.ToLower(level))];ok {
+		return level, true
+	}
+	return _maxLevel+1, false
+}
+
+func InitLogger(requested LogLevel) (*Logger, error) {
+	var logger *zap.Logger
+	var err error
+	switch requested {
+	case DebugLevel:
+		logger, err = initLoggerByLevel(zapcore.DebugLevel)
+	case InfoLevel:
+		logger, err = initLoggerByLevel(zapcore.InfoLevel)
+	case WarnLevel:
+		logger, err = initLoggerByLevel(zapcore.WarnLevel)
+	case ErrorLevel:
+		logger, err = initLoggerByLevel(zapcore.ErrorLevel)
+	case DPanicLevel:
+		logger, err = initLoggerByLevel(zapcore.DPanicLevel)
+	case PanicLevel:
+		logger, err = initLoggerByLevel(zapcore.PanicLevel)
+	case FatalLevel:
+		logger, err = initLoggerByLevel(zapcore.FatalLevel)
+	default:
+		err = fmt.Errorf("Invalid logging Level :%d",requested)
+	}
+	if err != nil {
+		return nil, err
+	}
+	return &Logger{Logger:logger}, nil
+
+}
+func(l *Logger)Sync() error {
+	l.Debugf("#logger.Sync - Going to flush buffered log")
+	return l.Logger.Sync()
+}
+
+func (l *Logger)Infof(formatMsg string, a ...interface{})  {
+	if l.InfoEnabled() {
+		msg := fmt.Sprintf(formatMsg, a...)
+		l.Logger.Info(msg, zap.Any("mdc", l.getTimeStampMdc()))
+	}
+}
+
+func (l *Logger)Debugf(formatMsg string, a ...interface{})  {
+	if l.DebugEnabled(){
+		msg := fmt.Sprintf(formatMsg, a...)
+		l.Logger.Debug(msg, zap.Any("mdc", l.getTimeStampMdc()))
+	}
+}
+
+func (l *Logger)Errorf(formatMsg string, a ...interface{})  {
+	msg := fmt.Sprintf(formatMsg, a...)
+	l.Logger.Error(msg, zap.Any("mdc", l.getTimeStampMdc()))
+}
+
+func (l *Logger)Warnf(formatMsg string, a ...interface{})  {
+	msg := fmt.Sprintf(formatMsg, a...)
+	l.Logger.Warn(msg, zap.Any("mdc", l.getTimeStampMdc()))
+}
+
+func (l *Logger) getTimeStampMdc() map[string]string {
+	timeStr := time.Now().Format("2006-01-02 15:04:05.000")
+	mdc := map[string]string{"time": timeStr}
+	return mdc
+}
+
+func (l *Logger)InfoEnabled()bool{
+	return l.Logger.Core().Enabled(zap.InfoLevel)
+}
+
+func (l *Logger)DebugEnabled()bool{
+	return l.Logger.Core().Enabled(zap.DebugLevel)
+}
+
+func (l *Logger)DPanicf(formatMsg string, a ...interface{})  {
+	msg := fmt.Sprintf(formatMsg, a...)
+	l.Logger.DPanic(msg, zap.Any("mdc", l.getTimeStampMdc()))
+}
+
+func initLoggerByLevel(l zapcore.Level) (*zap.Logger, error) {
+	cfg := zap.Config{
+		Encoding:         "json",
+		Level:            zap.NewAtomicLevelAt(l),
+		OutputPaths:      []string{"stdout"},
+		ErrorOutputPaths: []string{"stderr"},
+		EncoderConfig: zapcore.EncoderConfig{
+			MessageKey: "msg",
+
+			LevelKey:    "crit",
+			EncodeLevel: zapcore.CapitalLevelEncoder,
+
+			TimeKey:    "ts",
+			EncodeTime: epochMillisIntegerTimeEncoder,
+
+			CallerKey: "id",
+			EncodeCaller: e2ManagerCallerEncoder,
+		},
+	}
+	return cfg.Build()
+}
+
+func e2ManagerCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
+	enc.AppendString("E2Manager")
+}
+
+func epochMillisIntegerTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+	nanos := t.UnixNano()
+	millis := int64(nanos) / int64(time.Millisecond)
+	enc.AppendInt64(millis)
+}
+