Skip to content

Commit

Permalink
[FAB-6205] Improve log vendoring (populate flogging)
Browse files Browse the repository at this point in the history
This patch imports fabric flogging into SDK under third_party.

Change-Id: I805edd30d2b98eaeea33d87feafdbc09a7c7c4ea
Signed-off-by: Troy Ronda <troy.ronda@securekey.com>
  • Loading branch information
troyronda committed Sep 19, 2017
1 parent 4bfb47e commit eff58ec
Show file tree
Hide file tree
Showing 5 changed files with 335 additions and 11 deletions.
49 changes: 49 additions & 0 deletions scripts/third_party_pins/fabric/apply_fabric_external_utils.sh
@@ -0,0 +1,49 @@
#!/bin/bash
#
# Copyright SecureKey Technologies Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# This script pins the BCCSP package family from Hyperledger Fabric into the SDK
# These files are checked into internal paths.
# Note: This script must be adjusted as upstream makes adjustments

IMPORT_SUBSTS=($IMPORT_SUBSTS)

declare -a PKGS=(
"common/flogging"
)

declare -a FILES=(
"common/flogging/logging.go"
)

echo 'Removing current upstream project from working directory ...'
rm -Rf "${INTERNAL_PATH}/common/flogging"
mkdir -p "${INTERNAL_PATH}/common/flogging"

# Create directory structure for packages
for i in "${PKGS[@]}"
do
mkdir -p $INTERNAL_PATH/${i}
done

# Apply global import patching
echo "Patching import paths on upstream project ..."
for i in "${FILES[@]}"
do
for subst in "${IMPORT_SUBSTS[@]}"
do
sed -i '' -e $subst $TMP_PROJECT_PATH/${i}
done
goimports -w $TMP_PROJECT_PATH/${i}
done

# Copy patched project into internal paths
echo "Copying patched upstream project into working directory ..."
for i in "${FILES[@]}"
do
TARGET_PATH=`dirname $INTERNAL_PATH/${i}`
cp $TMP_PROJECT_PATH/${i} $TARGET_PATH
done
35 changes: 25 additions & 10 deletions scripts/third_party_pins/fabric/apply_upstream.sh
Expand Up @@ -14,8 +14,9 @@ UPSTREAM_BRANCH="master"
SCRIPTS_PATH="scripts/third_party_pins/fabric"
PATCHES_PATH="${SCRIPTS_PATH}/patches"

THIRDPARTY_FABRIC_API_PATH='api/third_party/fabric'
THIRDPARTY_FABRIC_BCCSP_PKG_PATH='pkg/third_party'
THIRDPARTY_FABRIC_PATH='third_party/github.com/hyperledger/fabric'
THIRDPARTY_FABRIC_API_PATH=$THIRDPARTY_FABRIC_PATH
THIRDPARTY_FABRIC_BCCSP_PKG_PATH=$THIRDPARTY_FABRIC_PATH
THIRDPARTY_INTERNAL_FABRIC_PATH='internal/github.com/hyperledger/fabric'

####
Expand Down Expand Up @@ -43,36 +44,50 @@ cd $CWD
# fabric client utils
echo "Pinning and patching fabric client utils..."
declare -a CLIENT_UTILS_IMPORT_SUBSTS=(
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/api\/third_party\/fabric\/protos\//g'
's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g'
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/protos\/utils/\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\/protos\/utils/g'
's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/protos\//g'
's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g'
)
eval "INTERNAL_PATH=$THIRDPARTY_INTERNAL_FABRIC_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${CLIENT_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_client_utils.sh"

# external utils
echo "Pinning and patching fabric external utils ..."
declare -a EXTERNAL_UTILS_IMPORT_SUBSTS=(
's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g'
)
eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${EXTERNAL_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_external_utils.sh"


# bccsp
echo "Pinning and patching bccsp ..."
declare -a BCCSP_IMPORT_SUBSTS=(
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g'
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g'
)
eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_BCCSP_PKG_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${BCCSP_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_bccsp.sh"

# protos
echo "Pinning and patching protos ..."
declare -a PROTOS_IMPORT_SUBSTS=(
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/api\/third_party\/fabric\/protos\//g'
's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g'
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/protos\//g'
's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g'
)
eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_API_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${PROTOS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_protos.sh"

# proto utils
echo "Pinning and patching proto utils..."
declare -a PROTO_UTILS_IMPORT_SUBSTS=(
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/api\/third_party\/fabric\/protos\//g'
's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g'
's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g'
's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/protos\//g'
's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g'
)
eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_API_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${PROTO_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_proto_utils.sh"
eval "INTERNAL_PATH=$THIRDPARTY_INTERNAL_FABRIC_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${PROTO_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_proto_utils.sh"

# Cleanup temporary files from patch application
echo "Removing temporary files ..."
Expand Down
@@ -0,0 +1,28 @@
From 81c8693fad42fa98ab38c8946fbb79d355e08392 Mon Sep 17 00:00:00 2001
From: Troy Ronda <t.....@securekey.com>
Date: Tue, 19 Sep 2017 11:29:58 -0400
Subject: [PATCH] Update package flogging for vendoring

Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0

Signed-off-by: Troy Ronda <t.....@securekey.com>
---
common/flogging/logging.go | 1 -
1 file changed, 1 deletion(-)

diff --git a/common/flogging/logging.go b/common/flogging/logging.go
index 841aed7a..f4f0b8d7 100644
--- a/common/flogging/logging.go
+++ b/common/flogging/logging.go
@@ -47,7 +47,6 @@ var (
func init() {
logger = logging.MustGetLogger(pkgLogID)
Reset()
- initgrpclogger()
}

// Reset sets to logging to the defaults defined in this package.
--
2.14.1

2 changes: 1 addition & 1 deletion test/scripts/unit.sh
Expand Up @@ -16,7 +16,7 @@ REPO="github.com/hyperledger/fabric-sdk-go"
PKGS=`go list $REPO... 2> /dev/null | \
grep -v ^$REPO/api/ | \
grep -v ^$REPO/pkg/fabric-ca-client/mocks | grep -v ^$REPO/pkg/fabric-client/mocks | \
grep -v ^$REPO/internal/github.com/ | grep -v ^$REPO/pkg/third_party/ | \
grep -v ^$REPO/internal/github.com/ | grep -v ^$REPO/third_party/ | \
grep -v ^$REPO/vendor/ | grep -v ^$REPO/test/`
echo "Running unit tests..."

Expand Down
232 changes: 232 additions & 0 deletions third_party/github.com/hyperledger/fabric/common/flogging/logging.go
@@ -0,0 +1,232 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
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 flogging

import (
"io"
"os"
"regexp"
"strings"
"sync"

"github.com/op/go-logging"
)

const (
pkgLogID = "flogging"
defaultFormat = "%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
defaultLevel = logging.INFO
)

var (
logger *logging.Logger

defaultOutput *os.File

modules map[string]string // Holds the map of all modules and their respective log level
peerStartModules map[string]string

lock sync.RWMutex
once sync.Once
)

func init() {
logger = logging.MustGetLogger(pkgLogID)
Reset()
}

// Reset sets to logging to the defaults defined in this package.
func Reset() {
modules = make(map[string]string)
lock = sync.RWMutex{}

defaultOutput = os.Stderr
InitBackend(SetFormat(defaultFormat), defaultOutput)
InitFromSpec("")
}

// SetFormat sets the logging format.
func SetFormat(formatSpec string) logging.Formatter {
if formatSpec == "" {
formatSpec = defaultFormat
}
return logging.MustStringFormatter(formatSpec)
}

// InitBackend sets up the logging backend based on
// the provided logging formatter and I/O writer.
func InitBackend(formatter logging.Formatter, output io.Writer) {
backend := logging.NewLogBackend(output, "", 0)
backendFormatter := logging.NewBackendFormatter(backend, formatter)
logging.SetBackend(backendFormatter).SetLevel(defaultLevel, "")
}

// DefaultLevel returns the fallback value for loggers to use if parsing fails.
func DefaultLevel() string {
return defaultLevel.String()
}

// GetModuleLevel gets the current logging level for the specified module.
func GetModuleLevel(module string) string {
// logging.GetLevel() returns the logging level for the module, if defined.
// Otherwise, it returns the default logging level, as set by
// `flogging/logging.go`.
level := logging.GetLevel(module).String()
return level
}

// SetModuleLevel sets the logging level for the modules that match the supplied
// regular expression. Can be used to dynamically change the log level for the
// module.
func SetModuleLevel(moduleRegExp string, level string) (string, error) {
return setModuleLevel(moduleRegExp, level, true, false)
}

func setModuleLevel(moduleRegExp string, level string, isRegExp bool, revert bool) (string, error) {
var re *regexp.Regexp
logLevel, err := logging.LogLevel(level)
if err != nil {
logger.Warningf("Invalid logging level '%s' - ignored", level)
} else {
if !isRegExp || revert {
logging.SetLevel(logLevel, moduleRegExp)
logger.Debugf("Module '%s' logger enabled for log level '%s'", moduleRegExp, level)
} else {
re, err = regexp.Compile(moduleRegExp)
if err != nil {
logger.Warningf("Invalid regular expression: %s", moduleRegExp)
return "", err
}
lock.Lock()
defer lock.Unlock()
for module := range modules {
if re.MatchString(module) {
logging.SetLevel(logging.Level(logLevel), module)
modules[module] = logLevel.String()
logger.Debugf("Module '%s' logger enabled for log level '%s'", module, logLevel)
}
}
}
}
return logLevel.String(), err
}

// MustGetLogger is used in place of `logging.MustGetLogger` to allow us to
// store a map of all modules and submodules that have loggers in the system.
func MustGetLogger(module string) *logging.Logger {
l := logging.MustGetLogger(module)
lock.Lock()
defer lock.Unlock()
modules[module] = GetModuleLevel(module)
return l
}

// InitFromSpec initializes the logging based on the supplied spec. It is
// exposed externally so that consumers of the flogging package may parse their
// own logging specification. The logging specification has the following form:
// [<module>[,<module>...]=]<level>[:[<module>[,<module>...]=]<level>...]
func InitFromSpec(spec string) string {
levelAll := defaultLevel
var err error

if spec != "" {
fields := strings.Split(spec, ":")
for _, field := range fields {
split := strings.Split(field, "=")
switch len(split) {
case 1:
if levelAll, err = logging.LogLevel(field); err != nil {
logger.Warningf("Logging level '%s' not recognized, defaulting to '%s': %s", field, defaultLevel, err)
levelAll = defaultLevel // need to reset cause original value was overwritten
}
case 2:
// <module>[,<module>...]=<level>
levelSingle, err := logging.LogLevel(split[1])
if err != nil {
logger.Warningf("Invalid logging level in '%s' ignored", field)
continue
}

if split[0] == "" {
logger.Warningf("Invalid logging override specification '%s' ignored - no module specified", field)
} else {
modules := strings.Split(split[0], ",")
for _, module := range modules {
logger.Debugf("Setting logging level for module '%s' to '%s'", module, levelSingle)
logging.SetLevel(levelSingle, module)
}
}
default:
logger.Warningf("Invalid logging override '%s' ignored - missing ':'?", field)
}
}
}

logging.SetLevel(levelAll, "") // set the logging level for all modules

// iterate through modules to reload their level in the modules map based on
// the new default level
for k := range modules {
MustGetLogger(k)
}
// register flogging logger in the modules map
MustGetLogger(pkgLogID)

return levelAll.String()
}

// SetPeerStartupModulesMap saves the modules and their log levels.
// this function should only be called at the end of peer startup.
func SetPeerStartupModulesMap() {
lock.Lock()
defer lock.Unlock()

once.Do(func() {
peerStartModules = make(map[string]string)
for k, v := range modules {
peerStartModules[k] = v
}
})
}

// GetPeerStartupLevel returns the peer startup level for the specified module.
// It will return an empty string if the input parameter is empty or the module
// is not found
func GetPeerStartupLevel(module string) string {
if module != "" {
if level, ok := peerStartModules[module]; ok {
return level
}
}

return ""
}

// RevertToPeerStartupLevels reverts the log levels for all modules to the level
// defined at the end of peer startup.
func RevertToPeerStartupLevels() error {
lock.RLock()
defer lock.RUnlock()
for key := range peerStartModules {
_, err := setModuleLevel(key, peerStartModules[key], false, true)
if err != nil {
return err
}
}
logger.Info("Log levels reverted to the levels defined at the end of peer startup")
return nil
}

0 comments on commit eff58ec

Please sign in to comment.