我在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"},哪个大神能帮我解答一下,我哪一步错了
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
根据您描述的问题,错误信息提示{"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格式。
构造JSON请求体:首先,确保您的请求体是一个有效的JSON字符串。如果您的日志数据原本是通过protobuf序列化的,您可能需要在发送前将protobuf数据转换为JSON格式。可以使用如Google的protobuf库中的JsonFormat函数来完成这一转换。
遵循API规范:仔细阅读阿里云日志服务API文档中关于写入日志的部分,了解如何正确构造POST请求。通常,您需要构造一个包含topic、source、logstore等字段的JSON对象作为日志的元数据,而日志内容则应放在相应的字段内,以JSON数组形式表示多条日志记录。
处理压缩与签名:在构造好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构造、压缩方式、签名算法等。