由于一些莫名其妙的原因,谷歌没有为appengine提供stackdriver api,所以我坚持实施一个。不用担心 - 我想 - 我已经与API构建器合作与bigquery交谈了,所以我建立了一个客户端并开始尝试发送事件:
credentials = SignedJwtAssertionCredentials(STACKDRIVER_AUTH_GOOGLE_CLIENT_EMAIL,
STACKDRIVER_AUTH_GOOGLE_PRIVATE_KEY,
scope='https://www.googleapis.com/auth/trace.append')
http = httplib2.Http()
credentials.refresh(http) #Working around an oauth2client bug
credentials = credentials.authorize(http)
service = build('cloudtrace', 'v1', http=http)
batch = service.new_batch_http_request()
batch.add(service.projects().patchTraces(
body=traces_json,
projectId=STACKDRIVER_AUTH_GOOGLE_PROJECT_ID))
print batch.execute()
我遗漏了traces_json的定义,因为无论发送什么,服务总是会响应错误。如果traces_json ='{}':
{u'error': {u'code': 400,
u'errors': [{u'domain': u'global',
u'message': u'Invalid value at \'traces\' (type.googleapis.com/google.devtools.cloudtrace.v1.Traces), "{}"',
u'reason': u'badRequest'}],
u'message': u'Invalid value at \'traces\' (type.googleapis.com/google.devtools.cloudtrace.v1.Traces), "{}"',
u'status': u'INVALID_ARGUMENT'}}
但即使我使用了一个由Google documentation制作的正文,我仍然会遇到同样的错误。
我在我正在尝试此操作的计算机上运行数据包嗅探器,并且很少看到它实际上与googleapis.com通信。
所以问题是,真的,我错过了什么让我发送事件到stackdriver?
更新
这是我一直在使用的最新版本,尽管使用google doc示例逐字(除了更改项目ID)会产生相同的结果。
{
"traces": [
{
"projectId": "projectname",
"traceId": "1234123412341234aaaabb3412347890",
"spans": [
{
"kind": "RPC_SERVER",
"name": "trace_name",
"labels": {"label1": "value1", "label2": "value2"},
"spanId": "spanId1",
"startTime": "2016-06-01T05:01:23.045123456Z",
"endTime": "2016-06-01T05:01:23.945123456Z",
},
],
},
],
}
随附的错误消息:
{u'error': {u'code': 400,
u'errors': [{u'domain': u'global',
u'message': u'Invalid value at \'traces\' (type.googleapis.com/google.devtools.cloudtrace.v1.Traces), "MY ENTIRE JSON IS REPEATED HERE"',
u'reason': u'badRequest'}],
u'message': u'Invalid value at \'traces\' (type.googleapis.com/google.devtools.cloudtrace.v1.Traces), "MY ENTIRE JSON IS REPEATED HERE"',
u'status': u'INVALID_ARGUMENT'}}
第二次更新
在资源管理器中执行此操作会产生大致相同的结果。我不得不切换到数字span_id,因为尽管docs声明它只需要一个唯一的字符串,但是当我提供任何其他内容时,我会得到关于要求看似64位整数的错误。
PATCH https://cloudtrace.googleapis.com/v1/projects/[number or name]/traces?key={YOUR_API_KEY}
{
"traces": [
{
"projectId": "[number or name]",
"traceId": "1234123412341234aaaabb3412347891",
"spans": [
{
"kind": "RPC_SERVER",
"name": "trace_name",
"labels": {
"label1": "value1"
},
"startTime": "2016-06-01T05:01:23.045123456Z",
"endTime": "2016-06-01T05:01:25.045123456Z"
},
{
"spanId": "0"
}
]
}
]
}
响应:
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT"
}
}
答案 0 :(得分:2)
问题在于您的数据格式。您也无法发送空消息。探索如何使用API的最佳方法是转到StackDriver Trace API资源管理器,您将找到要发送的确切数据结构: https://cloud.google.com/trace/api/reference/rest/v1/projects/patchTraces#traces
特别注意traceId的格式。它需要是32个字符的十六进制字符串,如下所示:7d9d1a6e2d1f3f27484992f33d97e5cb
这是一个工作的python示例,展示如何在github上使用StackDriver跟踪上的3个方法:https://github.com/qike/cloud-trace-samples-python
复制下面的粘贴代码:
def list_traces(stub, project_id):
"""Lists traces in the given project."""
trace_id = None
req = trace_pb2.ListTracesRequest(project_id=project_id)
try:
resp = stub.ListTraces(req, TIMEOUT)
for t in resp.traces:
trace_id = t.trace_id
print("Trace is: {}".format(t.trace_id))
except NetworkError, e:
logging.warning('Failed to list traces: {}'.format(e))
sys.exit(1)
return trace_id
def patch_traces(stub, project_id):
req = trace_pb2.PatchTracesRequest(project_id=project_id)
trace_id = str(uuid.uuid1()).replace('-', '')
now = time.time()
trace = req.traces.traces.add()
trace.project_id = project_id
trace.trace_id = trace_id
span1 = trace.spans.add()
span1.span_id = 1
span1.name = "/span1.{}".format(trace_id)
span1.start_time.seconds = int(now)-10
span1.end_time.seconds = int(now)
span2 = trace.spans.add()
span2.span_id = 2
span2.name = "/span2"
span2.start_time.seconds = int(now)-8
span2.end_time.seconds = int(now)-5
try:
resp = stub.PatchTraces(req, TIMEOUT)
print("Trace added successfully.\n"
"To view list of traces, go to: "
"http://console.cloud.google.com/traces/traces?project={}&tr=2\n"
"To view this trace added, go to: "
"http://console.cloud.google.com/traces/details/{}?project={}"
.format(project_id, trace_id, project_id))
except NetworkError, e:
logging.warning('Failed to patch traces: {}'.format(e))
sys.exit(1)
def get_trace(stub, project_id, trace_id):
req = trace_pb2.GetTraceRequest(project_id=project_id,
trace_id=trace_id)
try:
resp = stub.GetTrace(req, TIMEOUT)
print("Trace retrieved: {}".format(resp))
except NetworkError, e:
logging.warning('Failed to get trace: {}'.format(e))
sys.exit(1)
更新以回答从API资源管理器
收到的错误关于使用API资源管理器时遇到的错误,原因是使用0作为span_id。它应该是除0之外的64位int。
我还观察到你设置的span_id与你想要的span_id不同。确保不要错误地点击“+”符号来添加新的span对象。
以下是我通过API资源管理器发送到项目的成功补丁请求:
{
"traces": [
{
"projectId": "<project ID>", // I used string ID, not numeric number
"traceId": "1234123412341234aaaabb3412347891",
"spans": [
{
"spanId": "1",
"name": "foo",
"startTime": "2016-06-01T05:01:23.045123456Z",
"endTime": "2016-06-01T05:01:25.045123456Z"
}
]
}
]
}
Response
200