Golang中链码日志无法写入消息的解决方法

Golang中链码日志无法写入消息的解决方法 大家好,

我想调试链码中的函数,但找不到在链码日志中输出消息的方法。

我的代码如下:

var logger = shim.NewLogger("chaincode")
logger.Info("Get all the IDs and bytes value")

这是正确的方法吗?或者请分享相关链接,帮助我了解如何正确编写日志消息。

如果我想打印浮点数或字符串值,应该如何编写对应的日志消息?

2 回复

我不了解这个shim包,但如果它和内建日志记录器具有相同的函数,你可以使用Infof()函数在消息中写入数字。例如:

logger.Infof("%s has %d items", name, count)

更多关于Golang中链码日志无法写入消息的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Hyperledger Fabric链码中,使用shim.Logger是正确的日志记录方法。以下是详细的解决方案和示例:

1. 基本日志记录方法

您的代码是正确的,但需要确保正确初始化日志级别:

package main

import (
    "github.com/hyperledger/fabric-chaincode-go/shim"
    "github.com/hyperledger/fabric-protos-go/peer"
)

var logger = shim.NewLogger("chaincode")

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
    // 设置日志级别
    logger.SetLevel(shim.LogInfo)
    
    logger.Info("Chaincode initialization started")
    return shim.Success(nil)
}

2. 打印不同类型数据的示例

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
    function, args := stub.GetFunctionAndParameters()
    
    logger.Info("Get all the IDs and bytes value")
    
    // 打印字符串值
    name := "example_asset"
    logger.Infof("Asset name: %s", name)
    
    // 打印浮点数
    price := 99.99
    logger.Infof("Asset price: %.2f", price)
    
    // 打印整数
    quantity := 100
    logger.Infof("Quantity: %d", quantity)
    
    // 打印布尔值
    isActive := true
    logger.Infof("Is active: %t", isActive)
    
    // 打印结构体或复杂对象
    asset := struct {
        ID    string
        Value float64
    }{
        ID:    "asset001",
        Value: 123.45,
    }
    logger.Infof("Asset details - ID: %s, Value: %.2f", asset.ID, asset.Value)
    
    // 打印多个参数
    logger.Infof("Function: %s, Args count: %d", function, len(args))
    
    return shim.Success(nil)
}

3. 不同日志级别使用

func (t *SimpleChaincode) queryAsset(stub shim.ChaincodeStubInterface, assetID string) peer.Response {
    logger.Debug("Debug: Starting asset query")
    logger.Info("Info: Querying asset with ID: %s", assetID)
    
    value, err := stub.GetState(assetID)
    if err != nil {
        logger.Error("Error: Failed to get state for asset %s: %v", assetID, err)
        return shim.Error(err.Error())
    }
    
    if value == nil {
        logger.Warning("Warning: Asset %s not found", assetID)
        return shim.Error("Asset not found")
    }
    
    logger.Info("Successfully retrieved asset: %s", assetID)
    return shim.Success(value)
}

4. 完整的链码日志配置示例

package main

import (
    "encoding/json"
    "fmt"
    
    "github.com/hyperledger/fabric-chaincode-go/shim"
    "github.com/hyperledger/fabric-protos-go/peer"
)

type SimpleChaincode struct {
}

var logger = shim.NewLogger("myChaincode")

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
    logger.SetLevel(shim.LogDebug)
    logger.Info("=== Chaincode Initialization ===")
    
    // 初始化数据示例
    initialData := map[string]string{
        "key1": "value1",
        "key2": "value2",
    }
    
    for key, value := range initialData {
        err := stub.PutState(key, []byte(value))
        if err != nil {
            logger.Errorf("Failed to initialize key %s: %v", key, err)
            return shim.Error(err.Error())
        }
        logger.Infof("Initialized key: %s with value: %s", key, value)
    }
    
    logger.Info("=== Chaincode Initialization Completed ===")
    return shim.Success(nil)
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
    function, args := stub.GetFunctionAndParameters()
    logger.Infof("Invoke function: %s with args: %v", function, args)
    
    switch function {
    case "set":
        return t.setValue(stub, args)
    case "get":
        return t.getValue(stub, args)
    default:
        logger.Errorf("Unknown function: %s", function)
        return shim.Error("Unknown function")
    }
}

func (t *SimpleChaincode) setValue(stub shim.ChaincodeStubInterface, args []string) peer.Response {
    if len(args) != 2 {
        logger.Error("setValue requires 2 arguments: key and value")
        return shim.Error("Incorrect number of arguments")
    }
    
    key := args[0]
    value := args[1]
    
    logger.Infof("Setting key: %s, value: %s", key, value)
    
    err := stub.PutState(key, []byte(value))
    if err != nil {
        logger.Errorf("Failed to set state for key %s: %v", key, err)
        return shim.Error(err.Error())
    }
    
    logger.Info("Successfully set value")
    return shim.Success(nil)
}

func (t *SimpleChaincode) getValue(stub shim.ChaincodeStubInterface, args []string) peer.Response {
    if len(args) != 1 {
        logger.Error("getValue requires 1 argument: key")
        return shim.Error("Incorrect number of arguments")
    }
    
    key := args[0]
    logger.Infof("Getting value for key: %s", key)
    
    value, err := stub.GetState(key)
    if err != nil {
        logger.Errorf("Failed to get state for key %s: %v", key, err)
        return shim.Error(err.Error())
    }
    
    if value == nil {
        logger.Warningf("Key %s not found", key)
        return shim.Error("Key not found")
    }
    
    logger.Infof("Retrieved value: %s for key: %s", string(value), key)
    return shim.Success(value)
}

5. 日志格式说明

  • logger.Info("message") - 基本信息
  • logger.Infof("format", args...) - 格式化信息
  • logger.Debug/Debugf - 调试信息
  • logger.Warning/Warningf - 警告信息
  • logger.Error/Errorf - 错误信息

确保在链码部署时设置了正确的日志级别,日志消息将输出到Fabric节点的日志文件中。

回到顶部