diff --git a/include/types/proxy.h b/include/types/proxy.h --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -313,6 +313,8 @@ struct eb_root used_listener_id;/* list of listener IDs in use */ struct eb_root used_server_id; /* list of server IDs in use */ } conf; /* config information */ + + int do_unique_id; /* If true, turn on X-Unique-Id processing */ }; struct switching_rule { diff --git a/src/cfgparse.c b/src/cfgparse.c --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -4519,6 +4519,9 @@ free(err); } } + else if (!strcmp(args[0], "unique-id")) { /* enable X-Unique-Id processing */ + curproxy->do_unique_id = 1; + } else { struct cfg_kw_list *kwl; int index; diff --git a/src/proto_http.c b/src/proto_http.c --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2713,6 +2713,46 @@ /* transfer length unknown*/ txn->flags &= ~TX_REQ_XFER_LEN; + /* 4b: Insert header for tracing, if needed */ + if (s->fe->do_unique_id) { + ctx.idx = 0; + const char hdr[] = "X-Unique-Id"; + const size_t hdr_len = sizeof(hdr); + if (! http_find_header2(hdr, hdr_len, msg->sol, &txn->hdr_idx, &ctx)) { + const int max_counter = 1000; + static int id_counter = max_counter; + static char id_base[100]; // too lazy to figure out the exact minimum size needed + if (id_counter == max_counter) { + /* + * We want the ids to be unique, so they need lots of + * entropy. This is too expensive to do on every + * request. So, do this every max_counter requests + * and append a counter per request. I'm sure there + * are better ways to do this. + */ + long host_id; + pid_t pid; + struct timeval tv; + + host_id = gethostid(); + pid = getpid(); + gettimeofday(&tv, NULL); + snprintf(id_base, + sizeof(id_base), + "%s: %X.%X.%lX.%lX.", + hdr, + (unsigned int) host_id, + pid, + tv.tv_sec, + tv.tv_usec); + id_counter = 0; + } + char hdr_val[sizeof(id_base) + sizeof("1234567890")]; + snprintf(hdr_val, sizeof(hdr_val), "%s%d", id_base, id_counter++); + http_header_add_tail(req, &txn->req, &txn->hdr_idx, hdr_val); + } + } + /* 5: we may need to capture headers */ if (unlikely((s->logs.logwait & LW_REQHDR) && s->fe->req_cap)) capture_headers(msg->sol, &txn->hdr_idx,