static unsigned int vlog_reply(struct http_request *request, void *data) { struct vlog_req_priv vrp = { .limit = 10 }; int disp_status; char *p; char *tag = NULL; char *tag_re = NULL; struct VSL_data *vsl = NULL; struct VSLQ *vslq = NULL; struct VSL_cursor *c = NULL; enum VSL_grouping_e grouping = VSL_g_request; struct agent_core_t *core = data; p = next_slash(request->url + 1); if (p) { char *lim = strdup(p); assert(lim); char *tmp2 = strchr(lim, '/'); if (tmp2 && *tmp2) *tmp2 = '\0'; int j = sscanf(lim, "%u", &vrp.limit); if(j != 1) { free(lim); http_reply(request->connection, 500, "Not a number"); return 0; } free(lim); p = next_slash(p); } if (p) { tag = strdup(p); char *tmp2 = strchr(tag,'/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } if (p) { tag_re = strdup(p); char *tmp2 = strchr(tag_re, '/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } vrp.answer = VSB_new_auto(); assert(vrp.answer != NULL); vrp.vsm = VSM_New(); assert(vrp.vsm); if (!VSM_n_Arg(vrp.vsm, core->config->n_arg)) { VSB_printf(vrp.answer, "Error in creating shmlog: %s", VSM_Error(vrp.vsm)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } if (VSM_Open(vrp.vsm) != 0) { VSB_printf(vrp.answer, "Error in opening shmlog: %s", VSM_Error(vrp.vsm)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } vsl = VSL_New(); assert(vsl); if (tag) { grouping = VSL_g_raw; if (VSL_Arg(vsl, 'i', tag) < 0) { VSB_printf(vrp.answer, "Unable to specify tag '%s': %s", tag, VSL_Error(vsl)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } if (tag_re) { VSL_Arg(vsl,'I', tag_re); } } c = VSL_CursorVSM(vsl, vrp.vsm, VSL_COPT_BATCH | VSL_COPT_TAILSTOP); if (c == NULL) { VSB_printf(vrp.answer, "Can't open log (%s)", VSL_Error(vsl)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } vslq = VSLQ_New(vsl, &c, grouping, NULL); if (vslq == NULL) { VSB_clear(vrp.answer); VSB_printf(vrp.answer, "Error in creating query: %s", VSL_Error(vsl)); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } VSB_printf(vrp.answer, "{ \"log\": ["); do { disp_status = VSLQ_Dispatch(vslq, vlog_cb_func, &vrp); } while (disp_status == 1 && vrp.entries < vrp.limit); VSB_printf(vrp.answer, "\n] }\n"); assert(VSB_finish(vrp.answer) == 0); if (VSB_len(vrp.answer) > 1) { struct http_response *resp = http_mkresp(request->connection, 200, NULL); resp->data = VSB_data(vrp.answer); resp->ndata = VSB_len(vrp.answer); http_add_header(resp,"Content-Type","application/json"); send_response(resp); http_free_resp(resp); } else { http_reply(request->connection, 500, "FAIL"); } cleanup: free(tag); free(tag_re); VSB_delete(vrp.answer); if (vslq) VSLQ_Delete(&vslq); if (vsl) VSL_Delete(vsl); if (vrp.vsm) VSM_Delete(vrp.vsm); vrp.answer = NULL; return 0; } void vlog_init(struct agent_core_t *core) { struct agent_plugin_t *plug; struct vlog_priv_t *priv; ALLOC_OBJ(priv); plug = plugin_find(core,"vlog"); plug->data = priv; http_register_url(core, "/log", M_GET, vlog_reply, core); }
void VUT_Setup(void) { struct VSL_cursor *c; double t_start; int i; AN(VUT.vsl); AZ(VUT.vsm); AZ(VUT.vslq); /* Check input arguments */ if ((VUT.n_arg == NULL ? 0 : 1) + (VUT.N_arg == NULL ? 0 : 1) + (VUT.r_arg == NULL ? 0 : 1) > 1) VUT_Error(1, "Only one of -n, -N and -r options may be used"); /* Create and validate the query expression */ VUT.vslq = VSLQ_New(VUT.vsl, NULL, VUT.g_arg, VUT.q_arg); if (VUT.vslq == NULL) VUT_Error(1, "Query expression error:\n%s", VSL_Error(VUT.vsl)); /* Setup input */ if (VUT.r_arg) { REPLACE(VUT.name, VUT.r_arg); c = VSL_CursorFile(VUT.vsl, VUT.r_arg, 0); if (c == NULL) VUT_Error(1, "Can't open log file (%s)", VSL_Error(VUT.vsl)); } else { VUT.vsm = VSM_New(); AN(VUT.vsm); if (VUT.n_arg && VSM_n_Arg(VUT.vsm, VUT.n_arg) <= 0) VUT_Error(1, "%s", VSM_Error(VUT.vsm)); if (VUT.N_arg && VSM_N_Arg(VUT.vsm, VUT.N_arg) <= 0) VUT_Error(1, "%s", VSM_Error(VUT.vsm)); REPLACE(VUT.name, VSM_Name(VUT.vsm)); t_start = NAN; c = NULL; while (1) { i = VSM_Open(VUT.vsm); if (!i) c = VSL_CursorVSM(VUT.vsl, VUT.vsm, (VUT.d_opt ? VSL_COPT_TAILSTOP : VSL_COPT_TAIL) | VSL_COPT_BATCH); if (c) break; if (isnan(t_start) && VUT.t_arg > 0.) { VUT_Error(0, "Can't open log -" " retrying for %.0f seconds", VUT.t_arg); t_start = VTIM_real(); } VSM_Close(VUT.vsm); if (VUT.t_arg <= 0.) break; if (VTIM_real() - t_start > VUT.t_arg) break; VSM_ResetError(VUT.vsm); VSL_ResetError(VUT.vsl); VTIM_sleep(0.5); } if (VUT.t_arg >= 0. && (i || !c)) { if (i) VUT_Error(1, "Can't open VSM file (%s)", VSM_Error(VUT.vsm)); else VUT_Error(1, "Can't open log (%s)", VSL_Error(VUT.vsl)); } else if (!isnan(t_start)) VUT_Error(0, "Log opened"); } if (c) VSLQ_SetCursor(VUT.vslq, &c); AZ(c); /* Signal handlers */ (void)signal(SIGHUP, vut_sighup); (void)signal(SIGINT, vut_sigint); (void)signal(SIGTERM, vut_sigint); (void)signal(SIGUSR1, vut_sigusr1); /* Open PID file */ if (VUT.P_arg) { AZ(VUT.pfh); VUT.pfh = VPF_Open(VUT.P_arg, 0644, NULL); if (VUT.pfh == NULL) VUT_Error(1, "%s: %s", VUT.P_arg, strerror(errno)); } /* Daemon mode */ if (VUT.D_opt && varnish_daemon(0, 0) == -1) VUT_Error(1, "Daemon mode: %s", strerror(errno)); /* Write PID and setup exit handler */ if (VUT.pfh != NULL) { VPF_Write(VUT.pfh); AZ(atexit(vut_vpf_remove)); } }