int tee_create_stats(apr_pool_t *p, ap_scoreboard_e sb_type) { // Doing mmap()s so each child process has its reference to the shared area after fork() global_stats = mmap(NULL, sizeof(global_stats_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); global_stats->count = ap_get_scoreboard_global()->server_limit; ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, "tee: Creating stats for %d processes", global_stats->count); size_t array_size = sizeof(process_stats_t) * global_stats->count; global_stats->stats = mmap(NULL, array_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); apr_pool_t *global_pool; apr_pool_create(&global_pool, NULL); int i; for (i = 0; i < global_stats->count; i++) { /* * Pthread lock implies that: * - Child init function no needed * - Proc mutex (simpler) also works among threads, no need for global mutex */ apr_proc_mutex_create(&global_stats->stats[i].mutex, NULL, APR_LOCK_PROC_PTHREAD, global_pool); } /* * Saving pointer to global stats in pool userdata. This is necessary because the module * is unloaded during graceful restart, and globals are all zeroed. */ apr_pool_userdata_set(global_stats, STATUS_USERDATA_KEY, NULL, p); return OK; }
static PyObject *wsgi_server_metrics(void) { PyObject *scoreboard_dict = NULL; PyObject *process_list = NULL; PyObject *object = NULL; apr_time_t current_time; apr_interval_time_t running_time; global_score *gs_record; worker_score *ws_record; process_score *ps_record; int j, i; if (!wsgi_interns_initialized) wsgi_initialize_interned_strings(); /* Scoreboard needs to exist and server metrics enabled. */ if (!ap_exists_scoreboard_image()) { Py_INCREF(Py_None); return Py_None; } if (!wsgi_daemon_pool) { if (!wsgi_server_config->server_metrics) { Py_INCREF(Py_None); return Py_None; } } #if defined(MOD_WSGI_WITH_DAEMONS) else { if (!wsgi_daemon_process->group->server_metrics) { Py_INCREF(Py_None); return Py_None; } } #endif gs_record = ap_get_scoreboard_global(); if (!gs_record) { Py_INCREF(Py_None); return Py_None; } /* Return everything in a dictionary. Start with global. */ scoreboard_dict = PyDict_New(); object = wsgi_PyInt_FromLong(gs_record->server_limit); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(server_limit), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(gs_record->thread_limit); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(thread_limit), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(gs_record->running_generation); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(running_generation), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec(( double)gs_record->restart_time)); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(restart_time), object); Py_DECREF(object); current_time = apr_time_now(); object = PyFloat_FromDouble(apr_time_sec((double)current_time)); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(current_time), object); Py_DECREF(object); running_time = (apr_uint32_t)apr_time_sec((double) current_time - ap_scoreboard_image->global->restart_time); object = wsgi_PyInt_FromLongLong(running_time); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(running_time), object); Py_DECREF(object); /* Now add in the processes/workers. */ process_list = PyList_New(0); for (i = 0; i < gs_record->server_limit; ++i) { PyObject *process_dict = NULL; PyObject *worker_list = NULL; ps_record = ap_get_scoreboard_process(i); process_dict = PyDict_New(); PyList_Append(process_list, process_dict); object = wsgi_PyInt_FromLong(i); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(process_num), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(ps_record->pid); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(pid), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(ps_record->generation); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(generation), object); Py_DECREF(object); object = PyBool_FromLong(ps_record->quiescing); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(quiescing), object); Py_DECREF(object); worker_list = PyList_New(0); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(workers), worker_list); for (j = 0; j < gs_record->thread_limit; ++j) { PyObject *worker_dict = NULL; #if AP_MODULE_MAGIC_AT_LEAST(20071023,0) ws_record = ap_get_scoreboard_worker_from_indexes(i, j); #else ws_record = ap_get_scoreboard_worker(i, j); #endif worker_dict = PyDict_New(); PyList_Append(worker_list, worker_dict); object = wsgi_PyInt_FromLong(ws_record->thread_num); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(thread_num), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(ws_record->generation); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(generation), object); Py_DECREF(object); object = wsgi_status_flags[ws_record->status]; PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(status), object); object = wsgi_PyInt_FromLong(ws_record->access_count); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(access_count), object); Py_DECREF(object); object = wsgi_PyInt_FromUnsignedLongLong(ws_record->bytes_served); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(bytes_served), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec( (double)ws_record->start_time)); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(start_time), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec( (double)ws_record->stop_time)); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(stop_time), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec( (double)ws_record->last_used)); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(last_used), object); Py_DECREF(object); object = wsgi_PyString_FromString(ws_record->client); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(client), object); Py_DECREF(object); object = wsgi_PyString_FromString(ws_record->request); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(request), object); Py_DECREF(object); object = wsgi_PyString_FromString(ws_record->vhost); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(vhost), object); Py_DECREF(object); Py_DECREF(worker_dict); } Py_DECREF(worker_list); Py_DECREF(process_dict); } PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(processes), process_list); Py_DECREF(process_list); return scoreboard_dict; }