【Azure 应用服务】Azure JS Function 异步方法中日志无法输出问题引发的(await\async)关键字问题
问题描述
开发 Azure JS Function(NodeJS),使用 mssql 组件操作数据库。当SQL语句执行完成后,在Callback函数中执行日志输出 context.log(" ...") , 遇见如下错误:
Warning: Unexpected call to 'log' on the context object after function execution has completed.
Please check for asynchronous calls that are not awaited or calls to 'done' made before function execution completes.
Function name: HttpTrigger1. Invocation Id: e8c69eb5-fcbc-451c-8ee6-c130ba86c0e9. Learn more: https://go.microsoft.com/fwlink/?linkid=2097909
错误截图

问题解答
JS 函数代码(日志无法正常输出)
var sql = require('mssql');
var config = {
user: 'username',
password: 'Password',
server: '<server name>.database.chinacloudapi.cn', // You can use 'localhost\\instance' to connect to named instance
database: 'db name',
options: {
encrypt: true // Use this if you're on Windows Azure
}
}
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
await callDBtoOutput(context);
context.log('################');
//Default Code ...
const name = (req.query.name || (req.body && req.body.name));
const responseMessage = name
? "Hello, " + name + ". This HTTP triggered function executed successfully."
: "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";
context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage
};
}
async function callDBtoOutput(context) {
try {
context.log("Some Message from callDBtoOutput")
var ps = new sql.PreparedStatement(await sql.connect(config))
await ps.prepare('SELECT SUSER_SNAME() ', async function (err) {
if (err) {
context.log(err)
}
context.log("start to exec sql ...from callDBtoOutput")
await ps.execute({}, async function (err, recordset) {
// ... error checks
context.log(recordset)
context.log("Login SQL DB successfully....from callDBtoOutput")
ps.unprepare(function (err) {
// ... error checks
});
});
});
} catch (error) {
context.log(`Some Error Log: from callDBtoOutput`, error);
}
}
在 callDBtoOutput() 函数中,调用sql prepare 和 execute方法执行sql语句,虽然已经使用了async和await关键字,但根据测试结果表明:Function的主线程并不会等待callback函数执行。当主线程中context对象释放后,子线程中继续执行context.log函数时就会遇见以上警告信息。
为了解决以上prepare和execute方法中日志输出问题,需要使用其他执行sql的方法。在查看mssql的官方说明(https://www.npmjs.com/package/mssql#query-command-callback)后,发现query方法能够满足要求。
query (command, [callback])
Execute the SQL command. To execute commands like create procedure or if you plan to work with local temporary tables, use batch instead.
Arguments
- command - T-SQL command to be executed.
- callback(err, recordset) - A callback which is called after execution has completed, or an error has occurred. Optional. If omitted, returns Promise.
经过多次测试,以下代码能完整输出Function过程中产生的日志。
JS 函数执行SQL代码(日志正常输出)
var sql = require('mssql');
var config = {
user: 'username',
password: 'Password',
server: '<server name>.database.chinacloudapi.cn', // You can use 'localhost\\instance' to connect to named instance
database: 'db name',
options: {
encrypt: true // Use this if you're on Windows Azure
}
}
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
// context.log('call callDBtoOutput 1');
// await callDBtoOutput(context);
//context.log('call callDBtoOutput 2');
await callDBtoOutput2(context);
context.log('################');
const name = (req.query.name || (req.body && req.body.name));
const responseMessage = name
? "Hello, " + name + ". This HTTP triggered function executed successfully."
: "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";
context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage
};
}
async function callDBtoOutput2(context) {
context.log("1: Call SQL Exec function ....")
await sql.connect(config).then(async function () {
// Query
context.log("2: start to exec sql ... ")
await new sql.Request().query('SELECT SUSER_SNAME() ').then(async function (recordset) {
context.log("3: Login SQL DB successfully.... show the Query result")
context.log(recordset);
}).catch(function (err) {
// ... error checks
});
})
context.log("4: exec sql completed ... ")
}
结果展示(完整日志输出)

参考资料
node-mssql: https://www.npmjs.com/package/mssql
The
context.donemethod is deprecatedNow, it's recommended to remove the call to
context.done()and mark your function as async so that it returns a promise (even if you don'tawaitanything).
【Azure 应用服务】Azure JS Function 异步方法中日志无法输出问题引发的(await\async)关键字问题的更多相关文章
- 【Azure 应用服务】Azure Function集成虚拟网络,设置被同在虚拟网络中的Storage Account触发,遇见Function无法触发的问题
一切为了安全,所有的云上资源如支持内网资源访问,则都可以加入虚拟网络 问题描述 使用Azure Function处理Storage Account中Blob 新增,更新,删除等情况.Storage A ...
- 【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
问题描述 在.Net Core 5.0 项目中,添加 Microsoft.Extensions.Logging.AzureAppServices 和 Microsoft.Extensions.Logg ...
- 【Azure 应用服务】部署Kafka Trigger Function到Azure Function服务中,解决自定义域名解析难题
问题描述 经过前两篇文章,分别使用VM搭建了Kafka服务,创建了Azure Function项目,并且都在本地运行成功. [Azure Developer]在Azure VM (Windows) 中 ...
- 【Azure 应用服务】App Service/Azure Function的出站连接过多而引起了SNAT端口耗尽,导致一些新的请求出现超时错误(Timeout)
问题描述 当需要在应用中有大量的出站连接时候,就会涉及到SNAT(源地址网络转换)耗尽的问题.而通过Azure App Service/Function的默认监控指标图表中,却没有可以直接查看到SNA ...
- 【Azure 应用服务】Azure Function App使用SendGrid发送邮件遇见异常消息The operation was canceled,分析源码逐步最终源端
问题描述 在使用Azure Function App的SendGrid Binging功能,调用SendGrid服务器发送邮件功能时,有时候遇见间歇性,偶发性异常.在重新触发SendGrid部分的Fu ...
- 【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
问题描述 在App Service For Windows的环境中,我们可以通过ArmClient 工具发送POST请求在Web应用的实例中抓取网络日志,但是在App Service For Linu ...
- 【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑
编写Java Spring Boot应用,通过配置logging.path路径把日志输出在指定的文件夹中. 第一步:通过VS Code创建一个空的Spring Boot项目 第二步:在applicat ...
- 【Azure Developer】在Github Action中使用Azure/functions-container-action@v1配置Function App并成功部署Function Image
问题描述 使用Github Action,通过 Azure/functions-container-action@v1 插件来完成 yaml 文件的配置,并成功部署Function Image 的过程 ...
- Azure 应用服务中的 API 应用、ASP.NET 和 Swagger 入门
学习内容: 如何通过 Visual Studio 2015 中的内置工具在 Azure 应用服务中创建和部署 API 应用. 如何使用 Swashbuckle NuGet 包动态生成 Swagger ...
- 【Azure 应用服务】App Service中,为Java应用配置自定义错误页面,禁用DELETE, PUT方法
问题定义 使用Azure应用服务(App Service),部署Java应用,使用Tomcat容器,如何自定义错误页面呢?同时禁用DELETE, PUT方法 解决办法 如何自定义错误页面呢?需要在 J ...
随机推荐
- Hive不能载入本地数据:FAILED: SemanticException Line 1:17 Invalid path
1.问题描述: (1)问题示例: hive (test)> create table t_textfile(c1 string,c2 int,c3 string,c4 string) ...
- selenium--- 数据驱动测试 ddt
通过使用数据驱动测试的方法,可以在需要验证多组数据的测试场景中,使用外部数据源实现对输入值和期望值的参数化,从而避免在测试中仅使用硬编码的数据.将测试数据和测试脚本分离开,使得测试脚本在不同数据集合下 ...
- week3题解
1.寄包柜 看到题目最容易想到开二位数组 但数据量过大,因此需要map #include <bits/stdc++.h> using namespace std; map<int,m ...
- github fork 别人的项目源作者更新后如何同步更新
如下 左边选择我们拷贝的库 右边选择原工程 如下 点击箭头指向的位置 然后选择右边原工程目录
- 白鹭egret 控制屏幕方向
this.stage.orientation=fangxiang; fangxiang值: portrait landscape auto
- python def函数总结(格式、参数类型、传参方式、全局变量/局部变量、参数类型提示(Type Hints))
简单无参函数 编写脚本test1.py def register_user(): #函数名称只使用小写字母和下划线 """docstring""&qu ...
- 【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
问题描述 使用Azure Kubernetes服务(AKS),可以通过kubectl连接 pod 中查看日志,但是如何来查看节点的系统日志呢?如是否有ubuntu系统升级的记录? 问题解答 是的,可以 ...
- vulnhub靶场之BLUESMOKE: DEVRANDOM2|bluesmoke
准备: 攻击机:虚拟机kali.本机win10. 靶机:Bluesmoke: devrandom2,下载地址:https://download.vulnhub.com/bluesmoke/Bluesm ...
- SpringCloud Fegin 负载均衡
Spring Cloud Ribbon 和 Spring Cloud Hystrix 在微服务中实现了客户端负载均衡的服务调用以及通过断路器来保护微服务应用.这两者作为基础工具类框架广泛地应用在各个微 ...
- Wondershare Recovery - 万兴数据恢复专家,恢复你 Mac 上的重要文件
Wondershare Recoverit 是恢复被删除文件最有效的软件之一.计算机用户面临的一个主要问题是失去机密信息.我们可能是误删除了数据和文件,或者可能是由于病毒袭击.操作系统故障或硬盘故障而 ...