在python中,与stackdriver通信总是返回成功,不发送任何内容

时间:2016-06-01 21:36:48

标签: python google-app-engine google-api-python-client stackdriver google-cloud-monitoring

由于一些莫名其妙的原因,谷歌没有为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"
 }
}

Traces definition from the API "Try It!" page

1 个答案:

答案 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