V0 implementation of census_get_active_ops().

changes/60/217560/1
Hongyu Chen 10 years ago
parent 484bc53582
commit 1ef06e6285
  1. 64
      src/core/statistics/census_tracing.c
  2. 33
      src/core/statistics/census_tracing.h
  3. 71
      test/core/statistics/trace_test.c

@ -32,35 +32,19 @@
*/
#include "src/core/statistics/census_interface.h"
#include "src/core/statistics/census_tracing.h"
#include <stdio.h>
#include <string.h>
#include "src/core/statistics/census_rpc_stats.h"
#include "src/core/statistics/hash_table.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
/* Struct for a trace annotation. */
typedef struct annotation {
gpr_timespec ts; /* timestamp of the annotation */
char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */
struct annotation* next;
} annotation;
typedef struct trace_obj {
census_op_id id;
gpr_timespec ts;
census_rpc_stats rpc_stats;
char* method;
annotation* annotations;
} trace_obj;
static void trace_obj_destroy(trace_obj* obj) {
void trace_obj_destroy(trace_obj* obj) {
annotation* p = obj->annotations;
while (p != NULL) {
annotation* next = p->next;
@ -207,3 +191,45 @@ trace_obj* census_get_trace_obj_locked(census_op_id op_id) {
const char* census_get_trace_method_name(const trace_obj* trace) {
return (const char*)trace->method;
}
static annotation* dup_annotation_chain(annotation* from) {
annotation* to = NULL;
if (from != NULL) {
to = gpr_malloc(sizeof(annotation));
memcpy(to, from, sizeof(annotation));
to->next = dup_annotation_chain(from->next);
}
return to;
}
static trace_obj* trace_obj_dup(trace_obj* from) {
trace_obj* to = NULL;
GPR_ASSERT(from != NULL);
to = gpr_malloc(sizeof(trace_obj));
to->id = from->id;
to->ts = from->ts;
to->rpc_stats = from->rpc_stats;
to->method = gpr_strdup(from->method);
to->annotations = dup_annotation_chain(from->annotations);
return to;
}
trace_obj** census_get_active_ops(int* num_active_ops) {
trace_obj** ret = NULL;
gpr_mu_lock(&g_mu);
if (g_trace_store != NULL) {
size_t n = 0;
census_ht_kv* all_kvs = census_ht_get_all_elements(g_trace_store, &n);
*num_active_ops = n;
if (n != 0 ) {
size_t i = 0;
ret = gpr_malloc(sizeof(trace_obj *) * n);
for (i = 0; i < n; i++) {
ret[i] = trace_obj_dup((trace_obj*)all_kvs[i].v);
}
}
gpr_free(all_kvs);
}
gpr_mu_unlock(&g_mu);
return ret;
}

@ -34,12 +34,35 @@
#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_
#define __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_
#include <grpc/support/time.h>
#include "src/core/statistics/census_rpc_stats.h"
/* WARNING: The data structures and APIs provided by this file are for GRPC
library's internal use ONLY. They might be changed in backward-incompatible
ways and are not subject to any deprecation policy.
They are not recommended for external use.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Opaque structure for trace object */
typedef struct trace_obj trace_obj;
/* Struct for a trace annotation. */
typedef struct annotation {
gpr_timespec ts; /* timestamp of the annotation */
char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */
struct annotation* next;
} annotation;
typedef struct trace_obj {
census_op_id id;
gpr_timespec ts;
census_rpc_stats rpc_stats;
char* method;
annotation* annotations;
} trace_obj;
/* Deletes trace object. */
void trace_obj_destroy(trace_obj* obj);
/* Initializes trace store. This function is thread safe. */
void census_tracing_init(void);
@ -60,6 +83,12 @@ void census_internal_unlock_trace_store(void);
/* Gets method tag name associated with the input trace object. */
const char* census_get_trace_method_name(const trace_obj* trace);
/* Returns an array of pointers to trace objects of currently active operations
and fills in number of active operations. Returns NULL if there's no active
operations.
Caller owns the returned objects. */
trace_obj** census_get_active_ops(int* num_active_ops);
#ifdef __cplusplus
}
#endif

@ -32,10 +32,12 @@
*/
#include <string.h>
#include <stdio.h>
#include "src/core/statistics/census_interface.h"
#include "src/core/statistics/census_tracing.h"
#include "src/core/statistics/census_tracing.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/sync.h>
@ -172,6 +174,74 @@ static void test_trace_print(void) {
census_tracing_shutdown();
}
/* Returns 1 if two ids are equal, otherwise returns 0. */
static int ids_equal(census_op_id id1, census_op_id id2) {
return (id1.upper == id2.upper) && (id1.lower == id2.lower);
}
static void test_get_active_ops(void) {
census_op_id id_1, id_2, id_3;
trace_obj** active_ops;
const char* annotation_txt[] = {"annotation 1", "a2"};
int i = 0;
int n = 0;
gpr_log(GPR_INFO, "test_get_active_ops");
census_tracing_init();
/* No active ops before calling start_op(). */
active_ops = census_get_active_ops(&n);
GPR_ASSERT(active_ops == NULL);
GPR_ASSERT(n == 0);
/* Starts one op */
id_1 = census_tracing_start_op();
census_add_method_tag(id_1, "foo_1");
active_ops = census_get_active_ops(&n);
GPR_ASSERT(active_ops != NULL);
GPR_ASSERT(n == 1);
GPR_ASSERT(ids_equal(active_ops[0]->id, id_1));
trace_obj_destroy(active_ops[0]);
gpr_free(active_ops);
active_ops = NULL;
/* Start the second and the third ops */
id_2 = census_tracing_start_op();
census_add_method_tag(id_2, "foo_2");
id_3 = census_tracing_start_op();
census_add_method_tag(id_3, "foo_3");
active_ops = census_get_active_ops(&n);
GPR_ASSERT(n == 3);
for (i = 0; i < 3; i++) {
trace_obj_destroy(active_ops[i]);
}
gpr_free(active_ops);
active_ops = NULL;
/* End the second op and add annotations to the third ops*/
census_tracing_end_op(id_2);
census_tracing_print(id_3, annotation_txt[0]);
census_tracing_print(id_3, annotation_txt[1]);
active_ops = census_get_active_ops(&n);
GPR_ASSERT(active_ops != NULL);
GPR_ASSERT(n == 2);
for (i = 0; i < 2; i++) {
trace_obj_destroy(active_ops[i]);
}
gpr_free(active_ops);
active_ops = NULL;
/* End all ops. */
census_tracing_end_op(id_1);
census_tracing_end_op(id_3);
active_ops = census_get_active_ops(&n);
GPR_ASSERT(active_ops == NULL);
GPR_ASSERT(n == 0);
census_tracing_shutdown();
}
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
test_init_shutdown();
@ -180,5 +250,6 @@ int main(int argc, char** argv) {
test_concurrency();
test_add_method_tag_to_unknown_op_id();
test_trace_print();
test_get_active_ops();
return 0;
}

Loading…
Cancel
Save