【问题标题】:Custom message is not displayed in Azure Java Function AppAzure Java Function App 中不显示自定义消息
【发布时间】:2022-01-20 19:37:59
【问题描述】:

我已经从 az cli 在 Azure 中创建了一个 Java 函数,并且正在部署函数应用程序,但是当我访问函数应用程序 url 时,我在消息正文中看不到自定义消息。

以下是遵循的步骤: 1.编写了一个自定义的java程序LogFile.java从.log文件中读取数据 2.运行命令从 Maven 原型生成 Functions 项目,即 mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8

3.复制Function工程目录下的LogFile.java文件:/test/logfile-functions/src/main/java/com/logfile 4.Edited Function.java 代码以显示来自日志文件的消息,例如:

LogFile log = new LogFile()

return request.createResponseBuilder(HttpStatus.OK).body("日志文件消息:" + log.ReadLogData()).build();

5.运行 mvn clean package 命令构建项目并将JAR文件打包到目标目录 6.使用 mvn azure-functions:deploy 将函数项目部署到 Azure 门户中的新函数应用

函数应用程序正在 Azure 中部署,但是当我访问函数应用程序 URL 时,请求正文仅显示 日志文件消息: 而不是 日志文件消息:& 来自日志的消息文件。

但是在构建代码的步骤中会打印日志数据。 context.getLogger().info("日志文件消息:"+ log.ReadLogData());

请帮我解决这个问题

【问题讨论】:

    标签: java azure maven azure-functions


    【解决方案1】:

    尝试使用 log4j2,但日志不会出现在调用详细信息中,因此它们也不会出现在 Application Insights 查询中。

    Log4j2 日志显示在您的任何 Functions 应用程序的“日志流”部分下。但同样,这并没有真正的帮助。

    如果您已经使用其他日志记录框架内置了应用程序,那么您需要将所有日志记录更改为 java.util.logging 或执行以下操作。

    在单独的 Maven 模块中创建以下 2 个自定义类,并将其包含到所有功能模块中。具有与您正在使用的框架相同的包名称。就我而言,它的“org.apache.logging.log4j”

    它们不是完美构建的自定义类。但这行得通。

    LogManager.java

    package org.apache.logging.log4j;
    
    public class LogManager {
    static Logger logger = new Logger();
    
    public static Logger getLogger() {
        return logger;
    }
    
    public static void setLogger(Logger logger1) {
        logger = logger1;
    }
    
    public static Logger getLogger(Class<?> class1) {
        return logger;
    }
    
    public static Logger getLogger(String name) {
        return logger;
    }
    

    Logger.java

    package org.apache.logging.log4j;
    
    import java.util.logging.Level;
    
    public class Logger {
    private java.util.logging.Logger logger;
    
    public void setLogger(java.util.logging.Logger logger) {
        this.logger = logger;
    }
    
    public void debug(Object... obj) {
        printLog(obj, Level.FINE);
    }
    
    public void info(Object... obj) {
        printLog(obj, Level.INFO);
    }
    
    public void error(Object... obj) {
        printLog(obj, Level.SEVERE);
    }
    
    public void log(Object level, Object... obj) {
        printLog(obj, Level.FINEST);
    }
    
    public void warn(Object... obj) {
        printLog(obj, Level.WARNING);
    }
    
    private void printLog(Object[] obj, Level level) {
        if (obj != null) {
    
            String logString = obj[0] != null ? obj[0].toString() : "";
    
            if (obj.length > 1) {
                for (int i = 1; i < obj.length; i++) {
                    if (obj[i] != null) {
                        logString = logString.replaceFirst("\\{}", obj[i].toString());
                    }
                }                   
            }
            logger.log(level, logString);
        }
    }
    }
    

    然后您可以使用 Azure 的执行上下文设置您的自定义记录器。

    // LOG var Global to class    
    private final Logger LOG = LogManager.getLogger(BgdInfoAnalyticsHandler.class);
    
    @FunctionName("func-name-fn")
        public void run(
                @ServiceBusQueueTrigger(name = "TriggerName", queueName = "sbq-use-queue-name", connection = "AzureWebJobsServiceBus") String input,
                ExecutionContext context) {
            LOG.setLogger(context.getLogger());
            LogManager.setLogger(LOG);
            String fnInput = HostServiceUtil.getBlobData(input);
            LOG.info("fnInput : {} ", fnInput);
            invokeService(fnInput);
        }
    

    一旦使用 Azure 的 ExecutionContext 记录器在运行方法的入口点启动/设置此记录器。您可以通过执行 LogManager.getLogger(自定义类)从任何其他类获取此记录器,因为它是静态的。

    注意:静态变量由不同的调用或函数共享(如果它们驻留在同一个函数应用中)

    然后您可以在 Application Insights 中进行如下查询:

    union traces
    | union exceptions | union requests
    // | where timestamp > ago(2d)
    // | where cloud_RoleName =~ 'fun-use-function-app-name' and operation_Name =~ 'function-name-fn' //and operation_Id =~ "7303edd79433b0468f934c80a88e5f77"
    // | where innermostMessage contains "Exception" or message contains "Exception"
    | project timestamp, message = iff(message != '', message, 
        iff(innermostMessage != '', innermostMessage, customDimensions.['prop__{OriginalFormat}'])), logLevel = customDimensions.['LogLevel']
        , operation_Name, operation_Id, cloud_RoleName, invocationId=customDimensions['InvocationId']
    | order by timestamp asc
    | take 3000
    

    您还可以在以下位置查看失败/异常:ApplicationInsights > 调查部分 > 失败

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 2022-10-08
      • 1970-01-01
      • 2019-02-22
      • 2016-09-19
      相关资源
      最近更新 更多