4

由于某些莫名其妙的原因,谷歌没有为 appengine 提供 stackdriver api,所以我坚持实现一个。不用担心 - 我想 - 我已经与 API builder 合作过与 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'}}

但是,即使我使用从谷歌文档制作的正文,我仍然会遇到同样的错误。

我正在尝试此操作的机器上运行数据包嗅探器,并且很少看到它实际与 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 ,因为尽管文档声明它只能是一个唯一的字符串,但每当我提供其他任何内容时,我都会收到关于要求看起来是 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"
 }
}

来自 API 的跟踪定义

4

1 回答 1

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 explorer 得到的错误,这是由于使用 0 作为 span_id。它应该是 0 以外的 64 位整数。

我还观察到您设置的 span_id 与您想要的对象不同。确保您不会错误地单击“+”号来添加新的 span 对象。

以下是我通过 API Explorer 发送到我的项目的成功补丁请求:

{
 "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
于 2016-06-08T17:20:25.760 回答