尝试使用 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 > 调查部分 > 失败