开发者社区 问答 正文

用日志服务API遇到问题

我在windows平台上用c++开发用到阿里云日志服务,由于没有相应的SDK,我用API处理,按照协议,数据protobuf序列化、LZ4压缩、数字签名等这些都已经处理过,消息发送后返回400错误,{"errorCode":"ParameterInvalid","errorMessage":"The body is not valid json string"},我在通用错误码里没有找到相应的信息,说我的body是非法的json串,我的body的序列化是如下面这样做的:

std::string protobuf(const std::string& topic, const std::string& msg){ sls_logs::LogGroup pbLogGroup; sls_logs::Log* logPtr = pbLogGroup.add_logs();

CTime time = CTime::GetCurrentTime();
logPtr->set_time((google::protobuf::uint32)time.GetTime());

::sls_logs::Log_Content* content = logPtr->add_contents();
content->set_key("msg");
content->set_value(msg.c_str());

pbLogGroup.set_topic(topic.c_str());
pbLogGroup.set_source(utils::system::net_ip.c_str());
pbLogGroup.set_category(CanonicalizedResource());

std::string str = "";
if (!pbLogGroup.SerializeToString(&str)){
	return "";
}
return str;

} 请问我的问题在哪里?谢谢!

下面,我调用最简单的接口GetProject,生成的签名字符串为“GET\n\napplication/x-protobuf\nThu, 14 Nov 2019 05:08:07 GMT\nx-log-apiversion:0.6.0\nx-log-bodyrawsize:0\nx-log-signaturemethod:hmac-sha1\n/logstores/pcapp-test”,

hash签名并base64编码为:“IowCeYRcgOZdTQJPAxJvQhsWBV0=”,

生成http请求头为:“GET / HTTP/1.1

Authorization: LOG LTAI4Fpg1gmdndKzgBE3wFWd:IowCeYRcgOZdTQJPAxJvQhsWBV0=

Connection: Keep-Alive

Content-Length: 0

Content-Type: application/x-protobuf

Date: Thu, 14 Nov 2019 05:08:07 GMT

Host: qhjyrj.cn-hangzhou.log.aliyuncs.com

User-Agent: sls-cpp-sdk v0.6

x-log-apiversion: 0.6.0

x-log-bodyrawsize: 0

x-log-signaturemethod: hmac-sha1”,

请求收到的应答是:{"errorCode":"SignatureNotMatch","errorMessage":"signature IowCeYRcgOZdTQJPAxJvQhsWBV0= not match"},哪个大神能帮我解答一下,我哪一步错了

展开
收起
游客y63g4mowaejte 2019-11-13 12:09:53 1245 分享 版权
阿里云 AI 助理回答

根据您描述的问题,错误信息提示{"errorCode":"ParameterInvalid","errorMessage":"The body is not valid json string"}表明阿里云日志服务(Log Service)API期望接收到的是一个有效的JSON字符串,但实际接收到的并非如此。由于您提到使用了protobuf进行序列化,并且之后进行了LZ4压缩和数字签名,这可能是问题所在,因为直接发送protobuf序列化后的数据并不符合API要求的JSON格式。

在没有特定SDK的情况下,如果您需要通过API上传日志,您应该遵循阿里云日志服务API的文档要求,通常需要构造一个符合其规范的HTTP请求,其中请求体应该是JSON格式的数据。对于日志内容部分,即使原始数据是通过protobuf序列化的,也需要按照API要求转换为JSON格式。

解决方案:

  1. 构造JSON请求体:首先,确保您的请求体是一个有效的JSON字符串。如果您的日志数据原本是通过protobuf序列化的,您可能需要在发送前将protobuf数据转换为JSON格式。可以使用如Google的protobuf库中的JsonFormat函数来完成这一转换。

  2. 遵循API规范:仔细阅读阿里云日志服务API文档中关于写入日志的部分,了解如何正确构造POST请求。通常,您需要构造一个包含topicsourcelogstore等字段的JSON对象作为日志的元数据,而日志内容则应放在相应的字段内,以JSON数组形式表示多条日志记录。

  3. 处理压缩与签名:在构造好JSON请求体后,再进行LZ4压缩和添加数字签名。请确保这些步骤遵循阿里云API的指导,特别是签名过程,需要正确计算签名并附加到HTTP头中。

示例代码思路(非具体实现):

// 假设你已经有一个protobuf消息对象message
google::protobuf::util::JsonPrintOptions options;
options.add_whitespace = false; // 根据需要调整选项
std::string json_log_content;
google::protobuf::util::MessageToJsonString(message, &json_log_content, options);

// 构造完整的JSON请求体
std::string json_request_body = "{\"logs\":[{\"__source__\":\"your_source\",\"__topic__\":\"your_topic\",\"__tag__\":\"optional_tag\",\"contents\":[" + json_log_content + "]}]}";

// 然后对这个json_request_body进行LZ4压缩和签名处理...

请确保在实际操作中,每个步骤都严格遵循阿里云日志服务API的文档说明,包括但不限于HTTP头部设置、URL构造、压缩方式、签名算法等。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答