Azure Functions with java - 如何获取写入函数的日志?
Posted
技术标签:
【中文标题】Azure Functions with java - 如何获取写入函数的日志?【英文标题】:Azure Functions with java - How to get the logs written within the function? 【发布时间】:2019-12-09 21:34:53 【问题描述】:我在 Azure 中使用 Java 部署了一个队列触发的 azure 函数。我在pom.xml
中添加了logback-classic
和lombok
用于日志记录。
但是日志不会显示在函数的monitor > invocation details
或门户中的log-streaming service
上。
但我可以看到用context.getLogger()
编写的日志。带有 logback 记录器的日志写入器不可见。请让我知道如何检查我的函数调用日志。
以下是队列触发的天蓝色函数句柄
public class QueueHandlerFunction
@FunctionName("queuetriggertest")
public void queueMessageHandler(@QueueTrigger(name = "msg",
queueName = "my-test-queue", connection = "MyQStorage") final String payload,
final ExecutionContext context)
//Logs with this logger is visible
context.getLogger().info("Received Message From my-test-queue : " + payload);
MySampleService.handleQueueMessage(payload);
以下是带有 lombok 记录器的 MySampleService
类
@Slf4j
public class MySampleService
public static void handleQueueMessage(final String payload)
log.info("<<<<<<<<<<<< INSIDE THE SERVICE HANDLE >>>>>>>>>>>>");
if (StringUtils.isNotBlank(payload))
log.info("Received Payload : ", payload); //This log not available
// TODO Work with incoming payload
else
log.info("Message payload is Blank."); //This log not available
下面是他logback.xml
放在maven项目的resources文件夹中。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%dE MMM dd yyyy hh:mm:ss a [%thread] %-5level %logger36
- %msg%n</pattern>
</encoder>
</appender>
<logger name="com.howayig.test" level="INFO" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
我在pom.xml
中有以下依赖项
<dependencies>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
</dependencies>
编辑:附上函数调用日志的门户截图...
编辑 2:添加了本地执行的屏幕截图并在门户中部署了一个。
在本地执行时登录命令提示符
来自门户的功能的实时流媒体控制台服务,用于队列中的新消息
从门户中为队列中的新消息调用函数的详细信息
【问题讨论】:
这是否意味着appInsights
是我获取调用日志的唯一方法?该功能已经实现并且正在使用logback
来写入日志。我正在尝试使用 Azure 函数执行相同的功能。我想查看调用详细信息中的日志。见附图。但它只在那里显示上下文记录器日志。我应该在需要记录某些内容的地方使用这个上下文记录器吗?您可以看到日志语句属于不同的类。同样,执行流程中有更多日志。我得见他们。它会阻止来自其他记录器的日志条目吗?
换句话说,它在本地工作,但是当你部署到天蓝色时它不起作用?
你也一直在引用 invocation 日志。调用是什么意思?
Invocation 是指调用方法的行为。这是简单的英语。
调用意味着每当有新消息添加到队列时,该函数就会被执行(它是一个队列触发函数)。我用命令mvn clean package
打包函数。命令mvn azure-functions:run
用于在本地运行它。 mvn azure-functions:deploy
用于部署它。您可以看到语句 >>>>>>>>>>> 在本地运行时可见。但是 MySampleService
类中的日志语句在其部署在门户中时不可用(在日志流或调用详细信息中不可用)。
【参考方案1】:
你需要使用 Kudu。
获取应用的 URL,如果你的应用 URL 是 xxxxxxx.azurewebsites.net,则输入 xxxxxxx.scm.azurewebsites.net 查看日志。
【讨论】:
【参考方案2】:到目前为止,除了 java.util.logging 之外,没有其他日志框架可以工作。
我已尝试使用 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(自定义类)从任何其他类获取此记录器,因为它是静态的。
注意: Static vars are being shared by different invocations or functions (if they resides in same function app)
然后您可以在 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 > 调查部分 > 失败
【讨论】:
【参考方案3】:现在可以通过distributed tracing 获得。您可以从与以下requests, dependencies, logs and metrics.相关的函数应用程序中查看更丰富的数据
你只需要:
-
添加依赖:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>applicationinsights-core</artifactId>
<version>2.6.0</version>
</dependency>
-
创建一个名为 ApplicationInsights.json 的配置文件,内容如下:
"instrumentationSettings":
"connectionString": "InstrumentationKey=00000000-0000-0000-0000-000000000000"
-
创建 TelemetryClient:
private static final TelemetryClient telemetryClient = new TelemetryClient();
-
使用它
telemetryClient.trackTrace(message, SeverityLevel.Warning, properties);
【讨论】:
以上是关于Azure Functions with java - 如何获取写入函数的日志?的主要内容,如果未能解决你的问题,请参考以下文章
在 Java 中使用 Visual Studio Code 的 Azure Functions 项目
添加 Azure 存储 Blob 容器输入绑定 Azure Functions Java
将 FormData 对象读入 Java HTTP 触发的 Azure Functions
使用 Java Azure Functions SDK 处理二进制数据