????

Your IP : 3.128.78.255


Current Path : /root/mod_performance-master/
Upload File :
Current File : //root/mod_performance-master/mod_performance.c

/*
 * Copyright 2012 Alexey Berezhok (alexey_com@ukr.net, bayrepo.info@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * mod_performance.c (Apache 2.x)
 *
 *  Created on: Mar 12, 2011
 *  Author: SKOREE
 *  E-mail: alexey_com@ukr.net
 *  Site: lexvit.dn.ua
 *
 *  Описание:
 *  mod_performance - модуль для вычисления нагрузки, создаваемой сайтом
 *  Управляющие параметры
 *  PerformanceSocket - путь к сокету
 *  PerformanceEnabled - включить наблюдение
 *  PerformanceHostFilter - список отслеживаемых хостов
 *  PerformanceDB - путь к базе данных сведений
 *  PerformanceHistory - число дней хранения истории
 *  PerformanceWorkHandler - рабочий хандлер при котором выводится статистика
 *  PerformanceURI - регулярное выражение фильтра по URI
 *  PerformanceScript - регулярное выражение фильтра по имени скрипта
 *  PerformanceUserHandler - рабочий хандлер при котором выводится статистика для хоста
 *  PerformanceUseCanonical - использовать каноническое имя при логировании
 *  PerformanceLog - путь к файлу логов
 *  PerformanceLogFormat - формат выводимого лога (%DATE%, %CPU%, %MEM%, %URI%, %HOST%, %SCRIPT%, %EXCTIME%)
 *  PerformanceLogType - тип логирования информации (Log, SQLite, MySQL, Postgres)
 *  PerformanceDbUserName - пользователь для соединения с БД(MySQL,...)
 *  PerformanceDBPassword - пароль для соединения с БД(MySQL,...)
 *  PerformanceDBName - имя базы для соединения с БД(MySQL,...)
 *  PerformanceDBHost - хост БД(MySQL,...)
 *  PerformanceUseCPUTopMode - Irix/Solaris режим подсчета CPU % как в procps top (работает только в Linux)
 *  PerformanceCheckDaemonTimeExec - время выполнения демона, после его истечения демон перезапускается в секундах или в формате HH:MM:SS - т.е. время каждого дня, когда перезапускается демон
 *  PerformanceFragmentationTime - ежедневная дефрагментация базы данных. Только для MySQL
 *  PerformanceExternalScript - список скриптов, которые будут обрабатываться внешними модулями, например - mod_fcgid, mod_cgid, suphp...
 *  PerformanceMinExecTime - два параметра 1) число(в 1/100 секунды), 2) HARD/SOFT - задает минимальное время выполения скрипта и способ его сохранения HARD(не сохранять)/SOFT(сохранять с 0 %CPU)
 *  PerformanceSilentMode - On/Off включить или выключить молчаливый режим
 *  PerformanceSocketPermType - права доступа к сокету в формате ddd, например, 755 или 600..., а также имя сокета будет создаваться с PID{PID/NOPID} процесса или без него (PerformanceSocketPermType 600 PID)
 *  PerformanceUseTid - On/Off считать статистику по TID/PID
 *  PerformanceHostId - имя сервера для которого пишутся данные (по умолчанию localhost)
 *  PerformanceCustomReports - путь к файлу, описывающему отчеты
 *  PerformanceBlockedSocket - использовать блокирующий сокет
 *  PerformanceCustomPool - использовать не APR распределитель памяти
 *
 *  Deprecated
 *  PerformanceMaxThreads
 *  PerformanceStackSize
 *  PerformanceExtended
 *  PerformancePeriodicalWatch
 *
 */

/*
 * Если Apache 1.3 - прекратить сборку
 */
#ifdef APACHE1_3
#error "This source is for Apache version 2.0 or 2.2 only"
#endif

#if defined(linux)
#define PERF_SYSTEM_CHECK_OK 1
#endif
#if defined(__FreeBSD__)
#define PERF_SYSTEM_CHECK_OK 2
#endif

#ifndef PERF_SYSTEM_CHECK_OK
#error "This source is for linux or freebsd systems only"
#endif

#define CORE_PRIVATE

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#ifndef APACHE2_4
#include "mpm_default.h"
#endif
#include "unixd.h"
#include "ap_mpm.h"
#include "mod_log_config.h"
/*
 * Для Apache 2.0 этого заголовочного файла нет, поэтому regexp будем проверять
 * средствами системы.
 */
#ifndef APACHE2_0
#include "ap_regex.h"
#else
#include "regex.h"
#endif
#include "http_protocol.h"

#include "apr_strings.h"
#include "apr_thread_proc.h"
#include "apr_signal.h"
#include "apr_general.h"
#include "apr_hash.h"
#include "apr_tables.h"
#include "apr_time.h"
#include "apr_file_io.h"
#include "apr_optional.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <pthread.h>
#if defined(linux)
#include <linux/unistd.h>
#endif
#if defined(__FreeBSD__)
#include <unistd.h>
#endif
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#include <asm/param.h>
#include <poll.h>

#include <gd.h>
#include <gdfontt.h>
#include <gdfonts.h>
#include <gdfontmb.h>
#include <gdfontl.h>
#include <gdfontg.h>

#include "common.h"
#include "sql_adapter.h"
#include "reports.h"
#if defined(linux)
#include "iostat.h"
#endif
#if defined(__FreeBSD__)
#include "freebsd_getsysinfo.h"
#endif
#include "hertz-calcualtion.h"
#include "timers.h"
#include "chart.h"
#include "html-sources.h"
#include "tid_pid_list.h"
#include "custom_report.h"

#include "debug.h"

#include "tid_pid_list_ut.h"

#ifdef APACHE2_4
#define unixd_config ap_unixd_config
#define unixd_setup_child ap_unixd_setup_child
#endif

module AP_MODULE_DECLARE_DATA performance_module;

//Configuration structure
typedef struct performance_module_cfg {
	int performance_enabled;
	apr_array_header_t *performance_host_filter;
	const char *performance_work_handler;
	const char *performance_user_handler;
	apr_array_header_t *performance_uri;
	apr_array_header_t *performance_script;
	int performance_use_cononical_name;
	const char *performance_logname;
	apr_file_t *fd;
	const char *performance_log_format;
	apr_array_header_t *performance_log_format_parsed;
	apr_array_header_t *performance_external_handlers;
	apr_array_header_t *performance_host_filter_external;
} performance_module_cfg;

#define DAEMON_STARTUP_ERROR 254
#define DEFAULT_SOCKET  DEFAULT_REL_RUNTIMEDIR "/perfsocket"
#define DEFAULT_WORK_HANDLER "performance-status"
#define DEFAULT_USER_HANDLER "user-status"
#define DEFAULT_HISTORY_TIME 30
#define DEFAULT_DB  DEFAULT_REL_RUNTIMEDIR "/perfdb"
#define DEFAULT_PERF_LISTENBACKLOG 200
#define MODULE_INITIALIZATION_POINTER 0xFFFFFFFF
#define WATCH_PERIOD 10000
#define DELETE_INTERVAL 60*60*3
#define FORMAT_DEFAULT "[%DATE%] from %HOST% (%URI%) script %SCRIPT%: cpu %CPU% (%CPUS%), memory %MEM% (%MEMMB%), execution time %EXCTIME%, IO: R - %BYTES_R% W - %BYTES_W%"
#define DEFAULT_USERNAME "perf_user"
#define DEFAULT_PASSWORD "perf_password"
#define DEFAULT_DB_NAME "perf_db"
#define DEFAULT_DB_HOST "localhost"
#define DEFAULT_HOST_NAME "localhost"

#ifndef DEFAULT_CONNECT_ATTEMPTS
#define DEFAULT_CONNECT_ATTEMPTS  2
#endif

char gHostName[32];

glibtop_mem_own global_mem;

static char *performance_socket;
static char *performance_socket_no_pid;
static char *performance_db;
int performance_history;
static pid_t parent_pid;
static apr_proc_t daemon_proc;
apr_array_header_t *default_performance_log_format_parsed;
int log_type;
static char *performance_username;
static char *performance_password;
static char *performance_dbname;
static char *performance_dbhost;
static int performance_top;
static char *performance_check_extm;
static char *performance_db_defrag;
static int performance_silent_mode;

static long performance_min_exec_time = 123456789;
static apr_fileperms_t performance_socket_perm = 0x0000;
static int performance_use_pid = 1;
static int use_tid = 0;
static int performance_blocksave = 0;
static int performance_usecustompool = 1;

static apr_threadkey_t *key;

volatile int thread_should_stop = 0;
static volatile int daemon_should_exit = 0;
static apr_pool_t *pperf = NULL;
server_rec *root_server = NULL;
static apr_pool_t *root_pool = NULL;

char *template_path = NULL;

static int server_limit, thread_limit;

static pid_t child_pid;
static int registered_filter = 0;

apr_thread_mutex_t *mutex_db = NULL;

static __thread intptr_t sd_global = 0;
static __thread int filter_used = 0;

unsigned long long glbHtz;

#define BEGIN_SUB_POOL_SECTION(main_pool, pool) apr_pool_t *pool; \
                                                apr_pool_create (&pool, main_pool)

#define END_SUB_POOL_SECTION(main_pool, pool)   apr_pool_destroy(pool)

char *performance_paremeters[] = { "DATE", "CPU", "MEM", "URI", "HOST",
		"SCRIPT", "EXCTIME", "CPUS", "MEMMB", "BYTES_W", "BYTES_R" };

static int match_hostname(apr_array_header_t * allowed_hosts,
		const char *hostname);
static int match_script(apr_array_header_t * scripts_list,
		const char *script_name);

void init_global_mem() {
	memset(&global_mem, 0, sizeof(glibtop_mem_own));
#if defined(linux)
	glibtop_get_mem_own(&global_mem);
#endif
}

glibtop_mem_own *get_global_mem() {
	return &global_mem;
}

int get_use_tid() {
	return use_tid;
}

char *get_host_id() {
	return gHostName;
}

int performance_get_all_access() {
	module *mod;
	mod = ap_find_linked_module("mod_ruid2.c");
	if (mod)
		return 1;
	mod = ap_find_linked_module("itk.c");
	if (mod)
		return 1;
	return 0;
}

char *
performance_get_current_time_as_string(apr_pool_t * p) {
	apr_time_t tm;
	apr_time_exp_t te;
	apr_size_t retsize;
	char *tm_str = apr_palloc(p, 1024);
	tm = apr_time_now();
	apr_time_exp_lt(&te, tm);
	apr_strftime(tm_str, &retsize, 1024, "%Y-%m-%d %H:%M:%S", &te);
	return tm_str;
}

char *
performance_log_format_parse_param(apr_pool_t * p, char *str) {
	char *tmp = apr_pstrndup(p, str + 1, strlen(str) - 2);
	int i;
	for (i = 0; i < 11; i++) {
		if (!apr_strnatcasecmp(tmp, performance_paremeters[i]))
			return str;
	}

	if (!apr_strnatcasecmp(tmp, ""))
		return apr_pstrdup(p, "%");
	return NULL;
}

char *
performance_log_format_get_string(apr_pool_t * p, apr_array_header_t * arr,
		char *dateadd, char *uri, char *host, char *script, double cpu,
		double mem, double exc_time, double cpus, double memmb, double btrd,
		double btwr) {
	int i;
	char *str = apr_pstrdup(p, "");
	for (i = 0; i < arr->nelts; i++) {
		const char *s = ((const char **) arr->elts)[i];
		if ((*s == '%') && (strlen(s) > 1)) {
			if (!apr_strnatcasecmp(s, "%DATE%")) {
				str = apr_pstrcat(p, str, dateadd, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%CPU%")) {
				char *nmb = apr_psprintf(p, "%f", cpu);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%MEM%")) {
				char *nmb = apr_psprintf(p, "%f", mem);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%EXCTIME%")) {
				char *nmb = apr_psprintf(p, "%f", exc_time);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%URI%")) {
				str = apr_pstrcat(p, str, uri, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%HOST%")) {
				str = apr_pstrcat(p, str, host, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%SCRIPT%")) {
				str = apr_pstrcat(p, str, script, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%CPUS%")) {
				char *nmb = apr_psprintf(p, "%f", cpus);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%MEMMB%")) {
				char *nmb = apr_psprintf(p, "%f", memmb);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}
			if (!apr_strnatcasecmp(s, "%BYTES_W%")) {
				char *nmb = apr_psprintf(p, "%f", btrd);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}

			if (!apr_strnatcasecmp(s, "%BYTES_R%")) {
				char *nmb = apr_psprintf(p, "%f", btwr);
				str = apr_pstrcat(p, str, nmb, NULL);
				continue;
			}

		} else {
			str = apr_pstrcat(p, str, s, NULL);
		}
	}
	return str;
}

apr_array_header_t *
performance_log_format_parse(apr_pool_t * p, char *str) {
	apr_array_header_t *new_arr = apr_array_make(p, 1, sizeof(char *));

	char *beg_p = str;
	while (*str) {
		if (*str == '%') {
			if (beg_p != str) {
				if (*beg_p != '%') {
					*(char **) apr_array_push(new_arr) = apr_pstrndup(p, beg_p,
							str - beg_p);
					beg_p = str;
				} else {
					char *ptr = apr_pstrndup(p, beg_p, str - beg_p + 1);
					ptr = performance_log_format_parse_param(p, ptr);
					if (ptr) {
						*(char **) apr_array_push(new_arr) = ptr;
					}
					beg_p = str + 1;
				}
			}
		}
		str++;
	}

	if (beg_p != str) {
		if (*beg_p != '%') {
			*(char **) apr_array_push(new_arr) = apr_pstrndup(p, beg_p,
					str - beg_p);
			beg_p = str;
		} else {
			char *ptr = apr_pstrndup(p, beg_p, str - beg_p + 1);
			ptr = performance_log_format_parse_param(p, ptr);
			if (ptr) {
				*(char **) apr_array_push(new_arr) = ptr;
			}
			beg_p = str + 1;
		}
	}

	return new_arr;
}

static int performance_module_start(apr_pool_t * p, server_rec * main_server,
		apr_proc_t * procnew);

static int sqlite3_check_for_tables(apr_pool_t * p, server_rec * main_server) {

	char *err = sql_adapter_get_create_table(p, log_type, mutex_db);
	if (err) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "database table creation error: %s", err);
		return 0;
	}
	return 1;
}

static void sqlite3_save_request_info(apr_pool_t * p, server_rec * main_server,
		char *hostname, char *uri, char *script, double dtime, double dcpu,
		double dmemory, double dcpu_sec, double dmemory_mb, double dbr,
		double dbw) {

	apr_pool_t *inner_pool = NULL;
	if (apr_pool_create (&inner_pool, p) != APR_SUCCESS)
		return;
	char *err = sql_adapter_get_insert_table(inner_pool, log_type, hostname,
			uri, script, dtime, dcpu, dmemory, mutex_db, dcpu_sec, dmemory_mb,
			dbr, dbw);
	if (err) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "database insert error: %s", err);
	}

	//apr_pool_clear (inner_pool);
	apr_pool_destroy(inner_pool);
	return;

}

static void sqlite3_delete_request_info(apr_pool_t * p,
		server_rec * main_server, int keep_days) {

	apr_pool_t *inner_pool = NULL;
	if (apr_pool_create (&inner_pool, p) != APR_SUCCESS)
		return;
	char *err = sql_adapter_get_delete_table(inner_pool, log_type,
			performance_history, mutex_db);
	if (err) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "database deletion error: %s", err);
	}

	//apr_pool_clear (inner_pool);
	apr_pool_destroy(inner_pool);
	return;
}

static void daemon_signal_handler(int sig) {
	if (sig == SIGHUP) {
		++daemon_should_exit;
	}
}

static apr_status_t performance_read_data_from(int fd, void *vbuf,
		size_t buf_size) {
	char *buf = vbuf;
	int rc;
	size_t bytes_read = 0;

	do {
		do {
			errno = 0;
			rc = read(fd, buf + bytes_read, buf_size - bytes_read);
		} while (rc < 0 && errno == EINTR);
		switch (rc) {
		case -1:
			return errno;
		case 0: /* unexpected */
			return ECONNRESET;
		default:
			bytes_read += rc;
		}
	} while (bytes_read < buf_size);

	return APR_SUCCESS;
}

static apr_status_t performance_send_data_to(int fd, const void *buf,
		size_t buf_size) {
	int rc, __trys = 0;
	//int read_buffer = 0;

	//if(performance_blocksave){
	//	rc = read(fd, (void *)&read_buffer, sizeof(int));
	//}
	do {
		errno = 0;
		rc = write(fd, buf, buf_size);
		if (rc == buf_size)
			return APR_SUCCESS;
		__trys++;
		if (__trys > 10)
			return -1;
	} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
	if (rc < 0) {
		return errno;
	}

	return APR_SUCCESS;
}

static performance_module_cfg *
performance_module_sconfig(const request_rec * r) {
	return (performance_module_cfg *) ap_get_module_config(
			r->server->module_config, &performance_module);
}

static void *
create_performance_module_config(apr_pool_t * p, server_rec * s) {
	performance_module_cfg *c = (performance_module_cfg *) apr_pcalloc(p,
			sizeof(performance_module_cfg));

	c->performance_enabled = 0;
	c->performance_host_filter = NULL;
	c->performance_host_filter_external = NULL;
	c->performance_work_handler = apr_pstrdup(p, DEFAULT_WORK_HANDLER);
	c->performance_uri = NULL;
	c->performance_script = NULL;
	c->performance_user_handler = apr_pstrdup(p, DEFAULT_USER_HANDLER);
	c->performance_use_cononical_name = 0;
	c->performance_log_format = NULL;
	c->performance_log_format_parsed = NULL;
	c->performance_logname = NULL;
	c->fd = 0;
	c->performance_external_handlers = NULL;
	return c;
}

static void *
merge_performance_module_config(apr_pool_t * p, void *basev, void *overridesv) {
	performance_module_cfg *base = (performance_module_cfg *) basev,
			*overrides = (performance_module_cfg *) overridesv;

	performance_module_cfg *new = apr_palloc(p, sizeof(performance_module_cfg));
	memcpy(new, overrides, sizeof(performance_module_cfg));
	if (!new->performance_enabled) {
		new->performance_enabled = base->performance_enabled;
	}
	if (!new->performance_host_filter) {
		new->performance_host_filter = base->performance_host_filter;
	}
	if (!new->performance_host_filter_external) {
		new->performance_host_filter_external =
				base->performance_host_filter_external;
	}
	if (!new->performance_log_format) {
		new->performance_log_format = base->performance_log_format;
	}
	if (!new->performance_log_format_parsed) {
		new->performance_log_format_parsed =
				base->performance_log_format_parsed;
	}
	if (!new->performance_logname) {
		new->performance_logname = base->performance_logname;
	}
	if (!new->fd) {
		new->fd = base->fd;
	}
	if (!new->performance_script) {
		new->performance_script = base->performance_script;
	}
	if (!new->performance_uri) {
		new->performance_uri = base->performance_uri;
	}
	if (!new->performance_use_cononical_name) {
		new->performance_use_cononical_name =
				base->performance_use_cononical_name;
	}

	if (!new->performance_external_handlers) {
		new->performance_external_handlers =
				base->performance_external_handlers;
	}

	//return overrides->performance_work_handler ? overrides : base;
	return new;
}

static int performance_module_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
		apr_pool_t * ptemp) {
	performance_socket = ap_append_pid(pconf, DEFAULT_SOCKET, ".");
	performance_socket_no_pid = apr_pstrdup(pconf, DEFAULT_SOCKET);
	performance_history = DEFAULT_HISTORY_TIME;
	performance_db = apr_pstrdup(pconf, DEFAULT_DB);
	default_performance_log_format_parsed = performance_log_format_parse(pconf,
	FORMAT_DEFAULT);
	log_type = 1;
	performance_username = apr_pstrdup(pconf, DEFAULT_USERNAME);
	performance_password = apr_pstrdup(pconf, DEFAULT_PASSWORD);
	performance_dbname = apr_pstrdup(pconf, DEFAULT_DB_NAME);
	performance_dbhost = apr_pstrdup(pconf, DEFAULT_DB_HOST);
#if defined(linux)
	performance_top = 1;
#endif
	performance_check_extm = NULL;
	performance_db_defrag = NULL;
	performance_min_exec_time = 123456789;
	performance_silent_mode = 1;
	performance_socket_perm = 0000;
	performance_use_pid = 1;
	apr_cpystrn(gHostName, DEFAULT_HOST_NAME, sizeof(gHostName));
	template_path = NULL;
	performance_usecustompool = 1;
	performance_blocksave = 0;

	return OK;
}

static const char *
set_performance_module_socket(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_socket = ap_append_pid(cmd->pool, arg, ".");
	performance_socket = ap_server_root_relative(cmd->pool, performance_socket);
	performance_socket_no_pid = apr_pstrdup(cmd->pool, arg);
	performance_socket_no_pid = ap_server_root_relative(cmd->pool,
			performance_socket_no_pid);

	if (!performance_socket) {
		return apr_pstrcat(cmd->pool, "Invalid PerformanceSocket path", arg,
		NULL);
	}

	return NULL;
}

static const char *
set_performance_module_tpl_path(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	template_path = apr_pstrdup(cmd->pool, arg);
	template_path = ap_server_root_relative(cmd->pool, template_path);

	if (!template_path) {
		return apr_pstrcat(cmd->pool, "Invalid path to template", arg, NULL);
	}

	return NULL;
}

static const char *
set_performance_module_host_id(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}
	if (arg) {
		apr_cpystrn(gHostName, arg, sizeof(gHostName));
	}

	return NULL;
}

static const char *
set_performance_module_username(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_username = (char *) arg;

	if (!performance_username) {
		return apr_pstrcat(cmd->pool, "Invalid PerformanceDBUser name ", arg,
		NULL);
	}

	return NULL;
}

static const char *
set_performance_module_password(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_password = (char *) arg;

	if (!performance_password) {
		return apr_pstrcat(cmd->pool, "Invalid PerformanceDBPassword name ",
				arg, NULL);
	}

	return NULL;
}

static const char *
set_performance_module_db_name(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_dbname = (char *) arg;

	if (!performance_dbname) {
		return apr_pstrcat(cmd->pool, "Invalid PerformanceDBName name ", arg,
		NULL);
	}

	return NULL;
}

static const char *
set_performance_module_db_host(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_dbhost = (char *) arg;

	if (!performance_dbhost) {
		return apr_pstrcat(cmd->pool, "Invalid PerformanceDBHost name ", arg,
		NULL);
	}

	return NULL;
}

static const char *
set_performance_module_enabled(cmd_parms * cmd, void *dummy, const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);

	if (!apr_strnatcmp(arg, "On"))
		conf->performance_enabled = 1;
	else
		conf->performance_enabled = 0;
	return NULL;
}

static const char *
set_performance_module_tid(cmd_parms * cmd, void *dummy, const char *arg) {
	//server_rec *s = cmd->server;
	//performance_module_cfg *conf = ap_get_module_config (s->module_config,
	//		&performance_module);
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (!apr_strnatcmp(arg, "On"))
		use_tid = 1;
	else
		use_tid = 0;
	return NULL;
}

static const char *
set_performance_blocked_save(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (!apr_strnatcmp(arg, "On"))
		performance_blocksave = 1;
	else
		performance_blocksave = 0;
	return NULL;
}

static const char *
set_performance_custom_pool(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (!apr_strnatcmp(arg, "On"))
		performance_usecustompool = 1;
	else
		performance_usecustompool = 0;
	return NULL;
}

static const char *
set_performance_module_enabled_canonical(cmd_parms * cmd, void *dummy,
		const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);

	if (!apr_strnatcmp(arg, "On"))
		conf->performance_use_cononical_name = 1;
	else
		conf->performance_use_cononical_name = 0;
	return NULL;
}

#if defined(linux)
static const char *
set_performance_module_cpu_top(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (!apr_strnatcmp(arg, "Irix"))
		performance_top = 1;
	else if (!apr_strnatcmp(arg, "Solaris"))
		performance_top = 2;
	else
		performance_top = 1;
	return NULL;
}
#endif

static const char *
set_performance_module_cpu_top_depr(cmd_parms * cmd, void *dummy,
		const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - use new PerformanceUseCPUTopMode");
	return NULL;
}

static const char *
set_performance_module_silent_mode(cmd_parms * cmd, void *dummy,
		const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (!apr_strnatcmp(arg, "On"))
		performance_silent_mode = 1;
	else
		performance_silent_mode = 0;
	return NULL;
}

static apr_fileperms_t performance_convert_number_to_perm(int number) {
	apr_fileperms_t perm = 0;
	if (number & 0400)
		perm = perm | APR_FPROT_UREAD;
	if (number & 0200)
		perm = perm | APR_FPROT_UWRITE;
	if (number & 0100)
		perm = perm | APR_FPROT_UEXECUTE;
	if (number & 0040)
		perm = perm | APR_FPROT_GREAD;
	if (number & 0020)
		perm = perm | APR_FPROT_GWRITE;
	if (number & 0010)
		perm = perm | APR_FPROT_GEXECUTE;
	if (number & 0004)
		perm = perm | APR_FPROT_WREAD;
	if (number & 0002)
		perm = perm | APR_FPROT_WWRITE;
	if (number & 0001)
		perm = perm | APR_FPROT_WEXECUTE;
	return perm;
}

static const char *
set_performance_module_socket_perm(cmd_parms * cmd, void *dummy,
		const char *arg1, const char *arg2) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (arg1) {
		int tmp_perm = (int) apr_atoi64(arg1);
		int tmp_other = ((tmp_perm % 10) > 7 ? 7 : (tmp_perm % 10));
		;
		tmp_perm = tmp_perm / 10;
		int tmp_group = ((tmp_perm % 10) > 7 ? 7 : (tmp_perm % 10));
		tmp_perm = tmp_perm / 10;
		int tmp_user = ((tmp_perm % 10) > 7 ? 7 : (tmp_perm % 10));
		int tmp_mask = tmp_other | (tmp_group << 3) | (tmp_user << 6);
		performance_socket_perm = performance_convert_number_to_perm(tmp_mask);
	}
	if (arg2) {
		if (!apr_strnatcmp(arg2, "NOPID")) {
			performance_use_pid = 0;
		}
	}

	return NULL;
}

static const char *
set_performance_module_check_daemon_exctime(cmd_parms * cmd, void *dummy,
		const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_check_extm = (char *) arg;

	return NULL;
}

static const char *
set_performance_module_dboptimize(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_db_defrag = (char *) arg;

	return NULL;
}

static const char *
set_performance_module_cpu_exec_time(cmd_parms * cmd, void *dummy,
		const char *arg1, const char *arg2) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	int find_data = 0;

	performance_min_exec_time = apr_atoi64(arg1);
	if (!performance_min_exec_time) {
		performance_min_exec_time = apr_atoi64(arg2);
		if (!performance_min_exec_time) {
			return apr_pstrcat(cmd->pool,
					"Invalid PerformanceMinCPUExecTime directive. Wrong script execution length. Must be more then 0: ",
					arg2, NULL);
		}

		if (!apr_strnatcasecmp(arg1, "SOFT")) {
			performance_min_exec_time = performance_min_exec_time * 1;
			find_data++;
		}
		if (!apr_strnatcasecmp(arg1, "HARD")) {
			performance_min_exec_time = performance_min_exec_time * (-1);
			find_data++;
		}
		if (!find_data) {
			return apr_pstrcat(cmd->pool,
					"Invalid PerformanceMinCPUExecTime directive. Must be SOFT or HARD: ",
					arg1, NULL);
		}

	} else {
		if (!apr_strnatcasecmp(arg2, "SOFT")) {
			performance_min_exec_time = performance_min_exec_time * 1;
			find_data++;
		}
		if (!apr_strnatcasecmp(arg2, "HARD")) {
			performance_min_exec_time = performance_min_exec_time * (-1);
			find_data++;
		}
		if (!find_data) {
			return apr_pstrcat(cmd->pool,
					"Invalid PerformanceMinCPUExecTime directive. Must be SOFT or HARD: ",
					arg2, NULL);
		}

	}

	return NULL;
}

static const char *
set_performance_module_db(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_db = ap_server_root_relative(cmd->pool, arg);

	if (!performance_db) {
		return apr_pstrcat(cmd->pool, "Invalid PerformanceDB path ", arg, NULL);
	}

	return NULL;
}

static const char *
set_performance_module_history(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	performance_history = (int) apr_atoi64(arg);
	if (performance_history < 0) {
		return apr_pstrcat(cmd->pool,
				"Invalid PerformanceHistory value, less than 0", arg, NULL);
	}
	return NULL;
}

static const char *
set_performance_module_work_handler(cmd_parms * cmd, void *dummy,
		const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);

	conf->performance_work_handler = arg;

	if (!conf->performance_work_handler) {
		return apr_pstrcat(cmd->pool, "Invalid work handler ", arg, NULL);
	}
	return NULL;
}

static const char *
set_performance_module_log(cmd_parms * cmd, void *dummy, const char *arg) {
	performance_module_cfg *cfg = ap_get_module_config(
			cmd->server->module_config, &performance_module);
	cfg->performance_logname = arg;
	return NULL;
}

static const char *
set_performance_module_log_format(cmd_parms * cmd, void *dummy, const char *arg) {
	performance_module_cfg *cfg = ap_get_module_config(
			cmd->server->module_config, &performance_module);
	char *tmp_str = apr_pstrdup(cmd->pool, arg);
	cfg->performance_log_format_parsed = performance_log_format_parse(cmd->pool,
			tmp_str);

	return NULL;
}

static const char *
set_performance_module_log_type(cmd_parms * cmd, void *dummy, const char *arg) {
	const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}

	if (!apr_strnatcasecmp(arg, "Log")) {
		log_type = 0;
	}
	if (!apr_strnatcasecmp(arg, "SQLite")) {
		log_type = 1;
	}
	if (!apr_strnatcasecmp(arg, "MySQL")) {
		log_type = 2;
	}
	if (!apr_strnatcasecmp(arg, "Postgres")) {
		log_type = 3;
	}

	return NULL;
}

static const char *
set_performance_module_user_handler(cmd_parms * cmd, void *dummy,
		const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);

	conf->performance_user_handler = arg;

	if (!conf->performance_user_handler) {
		return apr_pstrcat(cmd->pool, "Invalid user handler ", arg, NULL);
	}
	return NULL;
}

static const char *
set_performance_module_host_filter(cmd_parms * cmd, void *dummy,
		const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);
	if (!conf->performance_host_filter) {
		conf->performance_host_filter = apr_array_make(cmd->pool, 2,
				sizeof(char *));
	}
	*(const char **) apr_array_push(conf->performance_host_filter) = arg;
	return NULL;
}

static const char *
set_performance_module_host_filter_external(cmd_parms * cmd, void *dummy,
		const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);
	if (!conf->performance_host_filter_external) {
		conf->performance_host_filter_external = apr_array_make(cmd->pool, 2,
				sizeof(char *));
	}
	*(const char **) apr_array_push(conf->performance_host_filter_external) =
			arg;
	return NULL;
}

static const char *
set_performance_module_external_handler(cmd_parms * cmd, void *dummy,
		const char *arg) {

	server_rec * s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);
	if (!conf->performance_external_handlers) {
		conf->performance_external_handlers = apr_array_make(cmd->pool, 2,
				sizeof(char *));
	}
	*(const char **) apr_array_push(conf->performance_external_handlers) = arg;
	return NULL;
}

static const char *
set_performance_module_uri(cmd_parms * cmd, void *dummy, const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);
	if (!conf->performance_uri) {
		conf->performance_uri = apr_array_make(cmd->pool, 2, sizeof(char *));
	}
	*(const char **) apr_array_push(conf->performance_uri) = arg;
	return NULL;
}

static const char *
set_performance_module_script(cmd_parms * cmd, void *dummy, const char *arg) {
	server_rec *s = cmd->server;
	performance_module_cfg *conf = ap_get_module_config(s->module_config,
			&performance_module);
	if (!conf->performance_script) {
		conf->performance_script = apr_array_make(cmd->pool, 2, sizeof(char *));
	}
	*(const char **) apr_array_push(conf->performance_script) = arg;
	return NULL;
}

void math_get_pcpu(double *dcpu, glibtop_cpu_own * current_cpu_beg,
		glibtop_proc_time_own * current_cpu_pid_beg, double current_tm_val_beg,
		glibtop_cpu_own * current_cpu_end,
		glibtop_proc_time_own * current_cpu_pid_end, double current_tm_val_end) {
#if defined(linux)
	int maxPCPU = ((performance_top == 2) ? 1 : get_cpu_num()) * 100;
#else
	int maxPCPU = 100;
#endif

	double dmaxPCPU = maxPCPU;
#if defined(linux)
	if (!performance_top) {
		uint64_t dtotal, dpu, dps;
		dtotal = current_cpu_end->total - current_cpu_beg->total;
		dpu = current_cpu_pid_end->utime - current_cpu_pid_beg->utime;
		dps = current_cpu_pid_end->stime - current_cpu_pid_beg->stime;

		if ((dtotal) > 0) {
			*dcpu = ((double) (dpu + dps) * 100.0) / ((double) (dtotal) * 1.0);
		}
	} else {
		float et;
		et = current_tm_val_end - current_tm_val_beg;

		if (et > 0.0) {
			long long tics = (current_cpu_pid_end->stime
					+ current_cpu_pid_end->utime)
					- (current_cpu_pid_beg->stime + current_cpu_pid_beg->utime);
			float Frame_tscale =
					100.0f
							/ ((float) 100.0 * (float) et
									* (float) (
											(performance_top == 2) ?
													get_cpu_num() : 1));
			*dcpu = (double) ((float) tics * Frame_tscale);
		}
	}
#endif
#if defined(__FreeBSD__)
	uint64_t dtotal, dpu, dps;
	dtotal = current_cpu_end->total - current_cpu_beg->total;
	dpu = current_cpu_pid_end->process_cpu - current_cpu_pid_beg->process_cpu;
	dps = current_cpu_pid_end->system_cpu - current_cpu_pid_beg->system_cpu;

	if ((dtotal) > 0)
	{
		*dcpu = ((double) (dpu + dps) * 100.0) / ((double) (dtotal) * 1.0);
	}
#endif

	if (*dcpu > dmaxPCPU) {
		*dcpu = dmaxPCPU;
	}

}

void math_get_io(double *dwrite, double *dread, iostat * old, iostat * new) {
#if defined(linux)
	double f_write_end = new->wchar;
	double f_write_beg = old->wchar;
	double f_write =
			(f_write_end > f_write_beg) ? (f_write_end - f_write_beg) : 0.0;
	double f_read =
			(new->rchar > old->rchar) ?
					(double) (new->rchar - old->rchar) : 0.0;

	*dwrite = f_write / 1024.0;
	*dread = f_read / 1024.0;
#endif
#if defined(__FreeBSD__)
	double f_write_end = new->io_write;
	double f_write_beg = old->io_write;
	double f_write =
	(f_write_end > f_write_beg) ? (f_write_end - f_write_beg) : 0.0;
	double f_read =
	(new->io_read >
			old->io_read) ? (double) (new->io_read - old->io_read) : 0.0;

	*dwrite = f_write;
	*dread = f_read;

#endif
}

void math_get_mem(float *memrate, float *membytes, glibtop_mem_own * memory,
		glibtop_proc_mem_own * procmem) {
#if defined(linux)
	*memrate = 100 * (procmem->resident) / ((memory->total) * 1.0); // calculate the memory usage

	*memrate = isnan (*memrate) ? 0.0 : *memrate;
	*memrate = isinf (*memrate) ? 0.0 : *memrate;

	if (membytes) {
		*membytes = procmem->resident;
		*membytes = *membytes / (1024 * 1024 * 1.0);
		*membytes = isnan (*membytes) ? 0.0 : *membytes;
		*membytes = isinf (*membytes) ? 0.0 : *membytes;
	}
#endif
#if defined(__FreeBSD__)

	*memrate = 100.0 * procmem->memory_percents;

	*memrate = isnan (*memrate) ? 0.0 : *memrate;
	*memrate = isinf (*memrate) ? 0.0 : *memrate;

	if (membytes)
	{
		*membytes = procmem->memory_bytes;
		*membytes = *membytes / (1024 * 1024 * 1.0);
		*membytes = isnan (*membytes) ? 0.0 : *membytes;
		*membytes = isinf (*membytes) ? 0.0 : *membytes;
	}

#endif

}

void performance_module_save_to_db(double req_time, apr_pool_t *pool,
		server_rec *srv, server_rec *server,
		performance_module_send_req *req_begin, double dcpu, double dmem,
		double dmem_mb, double dwrite, double dread, double dt) {
#if defined(linux)
	int maxPCPU = ((performance_top == 2) ? 1 : get_cpu_num()) * 100;
#else
	int maxPCPU = 100;
#endif

	double dmaxPCPU = maxPCPU;

	double dcput = dt * dcpu / dmaxPCPU;
	server_rec *req_server;
	apr_status_t retval;
	req_server = srv;

	if (req_time < (1.0 / glbHtz)) {
		dcpu = 0.0;
	}

	if (dcpu < 0.0) {
		dcpu = 0.0;

	}

	performance_module_cfg *cfg = NULL;
	cfg = ap_get_module_config(server->module_config, &performance_module);

	float check_min_script;
	int need_to_write = 1;
	if (performance_min_exec_time != 123456789) {
		if (performance_min_exec_time < 0) {
			check_min_script = -performance_min_exec_time;
		} else {
			check_min_script = performance_min_exec_time;
		}
		check_min_script = check_min_script / (float) 100;
		if (req_time < check_min_script) {
			if (performance_min_exec_time < 0) {
				need_to_write = 0;
			} else {
				dcpu = 0.0;
			}
		}
	}

	if (need_to_write) {
		if (cfg->performance_host_filter_external) {

				if (!match_hostname(cfg->performance_host_filter_external,
						req_begin->hostname))
					need_to_write = 0;


		}
	}

	if (need_to_write) {

		switch (log_type) {
		case 0: {
			BEGIN_SUB_POOL_SECTION(pool, _sub_pool);
			apr_size_t bytes_written;
			char *log_string;
			if (cfg && cfg->performance_logname && cfg->fd) {
				log_string = performance_log_format_get_string(_sub_pool,
						cfg->performance_log_format_parsed ?
								cfg->performance_log_format_parsed :
								default_performance_log_format_parsed,
						performance_get_current_time_as_string(_sub_pool),
						req_begin->uri, req_begin->hostname, req_begin->script,
						dcpu, dmem, dt, dcput, dmem_mb, dread, dwrite);
				log_string = apr_pstrcat(_sub_pool, log_string, "\n", NULL);

				bytes_written = strlen(log_string);
				retval = apr_file_write(cfg->fd, log_string, &bytes_written);
			}
			END_SUB_POOL_SECTION(pool, _sub_pool);
		}
			break;
		default: {
			sqlite3_save_request_info(pool, server, req_begin->hostname,
					req_begin->uri, req_begin->script, dt, dcpu, dmem, dcput,
					dmem_mb, dread, dwrite);
			break;
		}
		}
	}
}

static void performance_module_alarm(int sig) {
	if (sig == SIGALRM) {
		sqlite3_delete_request_info(root_pool, root_server,
				performance_history);
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, root_server,
				MODULE_PREFFIX "Deleting old performance items to trash was successfully");
		alarm(DELETE_INTERVAL);
	}
}

pid_t global_cur_pid = 0;

static void restar_daemon_interval(int sig, siginfo_t * si, void *uc) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, root_server,
			MODULE_PREFFIX " daemon will be restarted by scheduler. Next restart %s seconds",
			performance_check_extm ? performance_check_extm : "Ooops");
	daemon_should_exit++;
	;
}

static void restar_daemon_interval_val(int sig, siginfo_t * si, void *uc) {
	restar_daemon_interval(sig, si, uc);
	reset_timer(sig, performance_check_extm);
}

static void performance_db_defrag_action(int sig, siginfo_t * si, void *uc) {
	BEGIN_SUB_POOL_SECTION(pperf, _sub_pool);
	char *res = sql_adapter_optimize_table(_sub_pool, log_type, mutex_db);
	if (res) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, root_server,
				MODULE_PREFFIX "Data Base optimizing filed %s", res);
	} else {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, root_server,
				MODULE_PREFFIX "Data Base optimizing successful");
	}
	END_SUB_POOL_SECTION(pperf, _sub_pool);
	reset_timer(sig, performance_db_defrag);
}

struct pollfd *fds = NULL;
nfds_t nfds;

void cleanup_sock(int shut, int s, int howmany) {
	if (shut) {
		shutdown(s, howmany);
	}
	close(s);
}

void performance_server_main_cycle(int l_sock, server_rec *main_server,
		apr_pool_t *pool) {
	int ret;
	int timeout = 1000;
	init_global_mem();
	struct sockaddr_un fsaun;
	socklen_t fromlen = (socklen_t) sizeof(fsaun);
	nfds = 1;
	fds = (struct pollfd *) calloc(1, nfds * sizeof(struct pollfd));
	fds->fd = l_sock;
	fds->events = POLLIN;

	write_debug_info("Thread listen connection started");

	while (!daemon_should_exit) {
		if (performance_usecustompool)
			debug_tid_pid_ut();
		else
			debug_tid_pid();
		static int iteration = 1;
		write_debug_info("Thread listen iteration %d", iteration++);
		int i;
		//Wait max 1 second
		ret = poll(fds, nfds, timeout);
		if (ret == -1) {
			write_debug_info("Poll error %d", ret);
			if (errno != EINTR) {
				ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
						MODULE_PREFFIX"Error polling on socket");
				return;
			}
			/*TODO подумать- а что если все-таки доберется до конца дескрипторов
			 * тогда жесть начинается. errno = EINTR и при SIGALRM*/
			//++daemon_should_exit;
			continue;
		}
		write_debug_info("Thread listen get nfds %d", nfds);
		for (i = 0; (i < nfds) && (ret); i++) {
			if (!(fds + i)->revents)
				continue;
			ret--;

			if (((fds + i)->fd == l_sock) && ((fds + i)->revents & POLLIN)) {
				/*
				 * Accept
				 */
				fds = (struct pollfd *) realloc(fds,
						(nfds + 1) * sizeof(struct pollfd));
				(fds + nfds)->fd = accept(l_sock, (struct sockaddr *) &fsaun,
						&fromlen);

				write_debug_info("Thread listen accept socket %d",
						(fds + nfds)->fd);

				if ((fds + nfds)->fd == -1) {
					ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
							MODULE_PREFFIX "Error on polling socket. Accepting error");

					cleanup_sock(0, (fds + nfds)->fd, 1);
					fds = (struct pollfd *) realloc(fds,
							nfds * sizeof(struct pollfd));
					continue;
				}
				(fds + nfds)->events = POLLIN;
				nfds++;
				continue;
			}

			//Read
			if ((fds + i)->revents & POLLIN) {
				write_debug_info("Thread listen accept socket %d - Read info",
						(fds + i)->fd);
				performance_module_send_req message;
				if ((fds + i)->revents & POLLHUP) {
					while (performance_read_data_from((fds + i)->fd,
							(void *) &message,
							sizeof(performance_module_send_req)) == APR_SUCCESS) {
						if (performance_usecustompool)
							add_item_to_list_ut(&message, (fds + i)->fd);
						else
							add_item_to_list(&message, (fds + i)->fd);
					}
				} else {
					if (performance_read_data_from((fds + i)->fd,
							(void *) &message,
							sizeof(performance_module_send_req)) == APR_SUCCESS) {
						if (performance_usecustompool)
							add_item_to_list_ut(&message, (fds + i)->fd);
						else
							add_item_to_list(&message, (fds + i)->fd);
					} else {
						write_debug_info(
								"Thread listen accept socket %d - Error",
								(fds + i)->fd);
						//remove_pid_tid_data_fd((fds + i)->fd);
						if (performance_usecustompool)
							add_item_to_removelist_ut((fds + i)->fd);
						else
							add_item_to_removelist((fds + i)->fd);
						cleanup_sock(1, (fds + i)->fd, 2);
						nfds--;
						memcpy(fds + i, fds + i + 1,
								(nfds - i) * sizeof(struct pollfd));
						fds = (struct pollfd *) realloc(fds,
								nfds * sizeof(struct pollfd));
						continue;
					}
				}

			}

			//Not open
			if ((fds + i)->revents & POLLNVAL) {
				write_debug_info(
						"Thread listen close socket %d - Descriptor is not open. Just remove it from array",
						(fds + i)->fd);
				//remove_pid_tid_data_fd((fds + i)->fd);
				if (performance_usecustompool)
					add_item_to_removelist_ut((fds + i)->fd);
				else
					add_item_to_removelist((fds + i)->fd);
				nfds--;
				memcpy(fds + i, fds + i + 1,
						(nfds - i) * sizeof(struct pollfd));
				fds = (struct pollfd *) realloc(fds,
						nfds * sizeof(struct pollfd));
				continue;
			}
			//Disconnect
			if ((fds + i)->revents & POLLHUP) {
				//remove_pid_tid_data_fd((fds + i)->fd);
				if (performance_usecustompool)
					add_item_to_removelist_ut((fds + i)->fd);
				else
					add_item_to_removelist((fds + i)->fd);
				write_debug_info("Thread listen accept socket %d - Disconnect",
						(fds + i)->fd);
				cleanup_sock(0, (fds + i)->fd, 2);
				nfds--;
				memcpy(fds + i, fds + i + 1,
						(nfds - i) * sizeof(struct pollfd));
				fds = (struct pollfd *) realloc(fds,
						nfds * sizeof(struct pollfd));
				continue;
			}
			//Error
			if ((fds + i)->revents & POLLERR) {
				write_debug_info("Thread listen accept socket %d - Error",
						(fds + i)->fd);
				//remove_pid_tid_data_fd((fds + i)->fd);
				if (performance_usecustompool)
					add_item_to_removelist_ut((fds + i)->fd);
				else
					add_item_to_removelist((fds + i)->fd);
				ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
						MODULE_PREFFIX "Error on polling socket. Error %d",
						errno);

				cleanup_sock(0, (fds + i)->fd, 2);
				nfds--;
				memcpy(fds + i, fds + i + 1,
						(nfds - i) * sizeof(struct pollfd));
				fds = (struct pollfd *) realloc(fds,
						nfds * sizeof(struct pollfd));
				continue;
			}

		}

	}
	if (performance_usecustompool)
		destroy_tid_pid_ut();
	else
		destroy_tid_pid();
	return;
}

static void *APR_THREAD_FUNC proceed_data_every_second(apr_thread_t * thd,
		void *data) {
	apr_pool_t *pool = (apr_pool_t *) data;
	double old_tm = 0.0, new_tm = 0.0;
	struct timespec cur_tm;
	while (!daemon_should_exit) {
		if (performance_usecustompool)
			clean_item_list_ut(root_server, pool);
		else
			clean_item_list(root_server, pool);
		usleep(100000);
		//Check all table of tids
		clock_gettime(CLOCK_REALTIME, &cur_tm);
		new_tm = cur_tm.tv_sec + (double) cur_tm.tv_nsec / (double) SEC2NANO;
		if (old_tm == 0.0)
			old_tm = new_tm;
		if (performance_usecustompool)
			prcd_function_ut(pool, &old_tm, new_tm);
		else
			prcd_function(pool, &old_tm, new_tm);

	}
	return NULL;
}

static void *APR_THREAD_FUNC proceed_data_every_second2(apr_thread_t * thd,
		void *data) {
	apr_pool_t *pool = (apr_pool_t *) data;
	double old_tm = 0.0, new_tm = 0.0;
	struct timespec cur_tm;
	while (!daemon_should_exit) {
		usleep(1000000);
		//Check all table of tids
		clock_gettime(CLOCK_REALTIME, &cur_tm);
		new_tm = cur_tm.tv_sec + (double) cur_tm.tv_nsec / (double) SEC2NANO;
		if (old_tm == 0.0)
			old_tm = new_tm;

		if (performance_usecustompool)
			prcd_function2_ut(pool, &old_tm, new_tm);
		else
			prcd_function2(pool, &old_tm, new_tm);

	}
	return NULL;
}

static int performance_module_server(void *data) {

	struct sockaddr_un unix_addr;
	int sd, rc;
	mode_t omask;
	//apr_socklen_t len;
	server_rec *main_server = data;
	apr_status_t rv;

	apr_signal(SIGCHLD, SIG_IGN);
	apr_signal(SIGHUP, daemon_signal_handler);

	ap_close_listeners();

	if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "Couldn't create unix domain socket");
		return errno;
	}

	memset(&unix_addr, 0, sizeof(unix_addr));
	unix_addr.sun_family = AF_UNIX;
	if (!performance_use_pid)
		performance_socket = performance_socket_no_pid;
	apr_cpystrn(unix_addr.sun_path, performance_socket,
			sizeof unix_addr.sun_path);

	omask = umask(0077);
	rc = bind(sd, (struct sockaddr *) &unix_addr, sizeof(unix_addr));
	umask(omask);

	if (performance_get_all_access())
		rv = apr_file_perms_set(performance_socket,
				APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE
						| APR_FPROT_GREAD | APR_FPROT_GWRITE | APR_FPROT_WREAD
						| APR_FPROT_WWRITE);
	else
		rv = apr_file_perms_set(performance_socket,
		APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE);
	if (performance_socket_perm) {
		rv = apr_file_perms_set(performance_socket, performance_socket_perm);
	}
	if (rv != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_CRIT, rv, main_server,
				MODULE_PREFFIX "Couldn't set permissions on unix domain socket %s",
				performance_socket);
		close(sd);
		return rv;
	}

	if (listen(sd, DEFAULT_PERF_LISTENBACKLOG) < 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "Couldn't listen on unix domain socket");
		close(sd);
		return errno;
	}

	if (!geteuid()) {
		if (chown(performance_socket, unixd_config.user_id, -1) < 0) {
			ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
					MODULE_PREFFIX "Couldn't change owner of unix domain socket %s",
					performance_socket);
			close(sd);
			return errno;
		}
	}

	unixd_setup_child();

	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
			MODULE_PREFFIX "Performance daemon started successfully");
	if (log_type) {
		apr_signal(SIGALRM, performance_module_alarm);
		alarm(DELETE_INTERVAL);
		sqlite3_delete_request_info(pperf, main_server, performance_history);
	}

	//Устанавливаем таймер на перезапуск демона? если он установлен
	if (performance_check_extm) {
		long get_interval = gettimeinterval(performance_check_extm);
		if (!get_interval) {
			get_interval = apr_atoi64(performance_check_extm);
			if (get_interval) {
				//Задан интревал перезапуска
				addtimer(pperf, get_interval, 0, &restar_daemon_interval);
			}
		} else {
			//Задано время ежедневного запуска
			addtimer(pperf, get_interval, 1, &restar_daemon_interval_val);
		}

	}

	if (performance_db_defrag && (log_type == 2)) {
		long get_interval = gettimeinterval(performance_db_defrag);
		if (get_interval) {
			ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
					MODULE_PREFFIX "Optimize mode enabled");
			addtimer(pperf, get_interval, 1, &performance_db_defrag_action);
		}
	}

	apr_threadattr_t *thd_attr = NULL;
	apr_thread_t *thd_arr = NULL;
	apr_threadattr_create(&thd_attr, pperf);
	apr_threadattr_t *thd_attr2 = NULL;
	apr_thread_t *thd_arr2 = NULL;
	apr_threadattr_create(&thd_attr2, pperf);

	if (performance_usecustompool)
		init_tid_pid_ut(pperf);
	else
		init_tid_pid(pperf);

	rv = apr_thread_create(&thd_arr, thd_attr, proceed_data_every_second, pperf,
			pperf);
	if (rv != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
				MODULE_PREFFIX "Can't start memory watcher");
	} else {
		rv = apr_thread_create(&thd_arr2, thd_attr2, proceed_data_every_second2,
				pperf, pperf);
		if (rv != APR_SUCCESS) {
			ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
					MODULE_PREFFIX "Can't start counters saver");
			daemon_should_exit = 1;
			rv = apr_thread_join(&rv, thd_arr);
		} else {
			performance_server_main_cycle(sd, main_server, pperf);
			daemon_should_exit = 1;
			rv = apr_thread_join(&rv, thd_arr);
			rv = apr_thread_join(&rv, thd_arr2);
		}
	}

	apr_thread_mutex_destroy(mutex_db);
	close(sd);

	return -1;
}

#if APR_HAS_OTHER_CHILD
static void performance_module_maint(int reason, void *data, apr_wait_t status) {
	apr_proc_t *proc = data;
	int mpm_state;
	int stopping;

	switch (reason) {
	case APR_OC_REASON_DEATH:
		apr_proc_other_child_unregister(data);
		stopping = 1;
		if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state) == APR_SUCCESS
				&& mpm_state != AP_MPMQ_STOPPING) {
			stopping = 0;
		}
		if (!stopping) {
			if (status == DAEMON_STARTUP_ERROR) {
				ap_log_error(APLOG_MARK, APLOG_CRIT, errno, NULL,
						MODULE_PREFFIX "daemon failed to initialize");
			} else {
				ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL,
						MODULE_PREFFIX "daemon process died, restarting");
				performance_module_start(root_pool, root_server, proc);
			}
		}
		break;
	case APR_OC_REASON_RESTART:
		apr_proc_other_child_unregister(data);
		break;
	case APR_OC_REASON_LOST:
		apr_proc_other_child_unregister(data);
		performance_module_start(root_pool, root_server, proc);
		break;
	case APR_OC_REASON_UNREGISTER:
		kill(proc->pid, SIGHUP);
		if (unlink(
				performance_use_pid ?
						performance_socket : performance_socket_no_pid)
				< 0&& errno != ENOENT) {
			ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL,
					MODULE_PREFFIX "Couldn't unlink unix domain socket %s",
					performance_use_pid ?
							performance_socket : performance_socket_no_pid);
		}
		break;
	}
}
#endif

static int performance_module_start(apr_pool_t * p, server_rec * main_server,
		apr_proc_t * procnew) {
	apr_status_t rv;
	daemon_should_exit = 0;
	rv = apr_proc_fork(&daemon_proc, main_server->process->pool);
	if (rv == APR_INCHILD) { /* child */
		if (pperf == NULL) {
			apr_pool_create(&pperf, p);
			//ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
			//		MODULE_PREFFIX "Created pool %pp", pperf);
		}
		exit(performance_module_server(main_server) > 0 ?
		DAEMON_STARTUP_ERROR :
															-1);
	} else if (rv == APR_INPARENT) {
#if APR_HAS_OTHER_CHILD
		if (!procnew) {
			procnew = apr_pcalloc(main_server->process->pool, sizeof(*procnew));
		}
		procnew->pid = daemon_proc.pid;
		procnew->err = procnew->in = procnew->out = NULL;
		apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);
		apr_proc_other_child_register(procnew, performance_module_maint,
				procnew, NULL, p);
#endif
	} else {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "couldn't spawn daemon process");
		return DECLINED;
	}

	return OK;
}

static int performance_module_init(apr_pool_t * p, apr_pool_t * plog,
		apr_pool_t * ptemp, server_rec * main_server) {
	int return_value = OK, rc;
	const char *userdata_key = "performance_module_init";
	int first_time = 0;
	int *pDummy;
	apr_status_t rv;

	root_server = main_server;
	root_pool = p;

	performance_module_cfg *cfg = ap_get_module_config(
			main_server->module_config, &performance_module);
	performance_db = ap_server_root_relative(p, performance_db);

	if (log_type) {

		if (sql_adapter_load_library(p, log_type) < 0) {
			rc = 1;
			ap_log_error(APLOG_MARK, APLOG_WARNING, errno, main_server,
					MODULE_PREFFIX "Can't load db library");
		} else {

			if (sql_adapter_connect_db(p, log_type, performance_dbhost,
					performance_username, performance_password,
					performance_dbname, performance_db) < 0) {
				rc = 1;
				ap_log_error(APLOG_MARK, APLOG_WARNING, errno, main_server,
						MODULE_PREFFIX "Can't connect to db");
			} else
				rc = OK;
		}
	} else {
		rc = OK;
	}
	if (rc) {
		cfg->performance_enabled = 0;
		ap_log_error(APLOG_MARK, APLOG_WARNING, errno, main_server,
				MODULE_PREFFIX "Internal error, performance module will be disabled :(");
	} else {

		if (log_type == 1) {
			rv = apr_file_perms_set(performance_db,
			APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE);
			if (rv != APR_SUCCESS) {
				ap_log_error(APLOG_MARK, APLOG_CRIT, rv, main_server,
						MODULE_PREFFIX "Couldn't set permissions on database file %s",
						performance_db);
				cfg->performance_enabled = 0;
			}
			if (!geteuid()) {
				if (chown(performance_db, unixd_config.user_id, -1) < 0) {
					ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
							MODULE_PREFFIX "Couldn't change owner of database file %s",
							performance_db);
					cfg->performance_enabled = 0;
				}
			}
		}

		apr_status_t rv_tmp = apr_thread_mutex_create(&mutex_db,
		APR_THREAD_MUTEX_DEFAULT, main_server->process->pool);
		if (rv_tmp != APR_SUCCESS) {
			cfg->performance_enabled = 0;
			ap_log_error(APLOG_MARK, APLOG_WARNING, errno, main_server,
					MODULE_PREFFIX "Internal error(can't create db mutex), performance module will be disabled :(");
		}

		if (log_type) {
			if (!sqlite3_check_for_tables(p, main_server)) {
				cfg->performance_enabled = 0;
			}
		}
	}

#if defined(__FreeBSD__)
	if (init_freebsd_info ())
	{
		cfg->performance_enabled = 0;
		ap_log_error (APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "Init FreeBSD info failed");
	}
	glbHtz = (unsigned long long) getstathz ();

#endif

#if defined(linux)
	glbHtz = init_libproc();
#endif

	if (glbHtz == (unsigned long long) -1) {
		cfg->performance_enabled = 0;
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "CPU HZ identification failed");
	}

#if defined(linux)
	if (glibtop_init_own() < 0) {
		cfg->performance_enabled = 0;
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
				MODULE_PREFFIX "pseudo glib_top_init failed");
	}
#endif

	apr_pool_userdata_get((void **) &pDummy, userdata_key,
			main_server->process->pool);
	if (!pDummy) {
		pDummy = apr_palloc(main_server->process->pool, sizeof(int));
		*pDummy = 1;
		apr_pool_userdata_set((void *) pDummy, userdata_key,
				apr_pool_cleanup_null, main_server->process->pool);
		first_time = 1;
	}

	inittimer();

	if (!first_time) {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
				MODULE_PREFFIX "version " PERFORMANCE_MODULE_VERSION " loaded");
	}

	if (cfg->performance_enabled) {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
				MODULE_PREFFIX "module enabled :)");

		if (!first_time) {
			parent_pid = getpid();
			performance_socket = ap_server_root_relative(p, performance_socket);
			performance_socket_no_pid = ap_server_root_relative(p,
					performance_socket_no_pid);
			return_value = performance_module_start(p, main_server, NULL);
			if (return_value != OK) {
				return return_value;
			}
			ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
					MODULE_PREFFIX "server started :)");
		}
	} else {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
				MODULE_PREFFIX "module disabled :(");
	}

	ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
	ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);

	if (template_path) {
		custom_report_parse_reports(template_path, p);
	}

	if (registered_filter) {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
				MODULE_PREFFIX " use filter");
	} else {
		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
				MODULE_PREFFIX " use log hook");
	}

	return return_value;
}

static int match_hostname(apr_array_header_t * allowed_hosts,
		const char *hostname) {
	int num_names;
	char **names_ptr;
	int accept = 0;
	if (!hostname)
		return accept;
	if (allowed_hosts) {
		names_ptr = (char **) allowed_hosts->elts;
		num_names = allowed_hosts->nelts;
	} else {
		return accept;
	}
	// match handle
	for (; num_names; ++names_ptr, --num_names) {
		if (strstr(hostname, *names_ptr)) {
			accept = 1;
			break;
		}
	}
	return accept;
}

// returns 1 if found, 0 if not
static int match_script(apr_array_header_t * scripts_list,
		const char *script_name) {
	int num_names;
	char **names_ptr;

#ifndef APACHE2_0
	ap_regex_t compiled_regex;
#else
	regex_t compiled_regex;
#endif

	if (scripts_list && script_name) {
		names_ptr = (char **) scripts_list->elts;
		num_names = scripts_list->nelts;

		for (; num_names; ++names_ptr, --num_names) {
			if (!strcmp("*", *names_ptr))
				return 1;

#ifndef APACHE2_0
			if (ap_regcomp(&compiled_regex, *names_ptr,
			AP_REG_EXTENDED | AP_REG_NOSUB))
				continue;

			if (!ap_regexec(&compiled_regex, script_name, 0, NULL, 0)) {
				ap_regfree(&compiled_regex);
				return 1;
			} else {
				ap_regfree(&compiled_regex);
				continue;
			}
#else

			if (regcomp (&compiled_regex, *names_ptr, REG_EXTENDED | REG_NOSUB))
			continue;

			if (!regexec (&compiled_regex, script_name, 0, NULL, 0))
			{
				regfree (&compiled_regex);
				return 1;
			}
			else
			{
				regfree (&compiled_regex);
				continue;
			}

#endif

		}
	}

	return 0;
}

static int own_connect(int socket, struct sockaddr *addr, socklen_t length) {
	errno = 0;
	if (!performance_blocksave) {
		int rt_code, rt_code2;
		struct pollfd fds;
		int nfds = 1;
		rt_code = fcntl(socket, F_GETFL, 0);
		rt_code2 = fcntl(socket, F_SETFL, rt_code | O_NONBLOCK);

		int ret = 0;
		int timeout = 100;

		fds.fd = socket;
		fds.events = POLLOUT;

		if ((ret = connect(socket, (struct sockaddr *) addr, length)) == -1) {
			if ( errno != EINPROGRESS)
				return -1;

		} else {
			return ret;
		}
		ret = poll(&fds, nfds, timeout);
		return (ret > 0) ? ret : -1;
	} else {
		return connect(socket, (struct sockaddr *) addr, length);
	}

}

static int connect_to_daemon(intptr_t * sdptr, request_rec * r) {
	struct sockaddr_un unix_addr;
	intptr_t sd;
	int connect_tries;
	apr_interval_time_t sliding_timer;

	memset(&unix_addr, 0, sizeof(unix_addr));
	unix_addr.sun_family = AF_UNIX;
	apr_cpystrn(unix_addr.sun_path,
			performance_use_pid ?
					performance_socket : performance_socket_no_pid,
			sizeof unix_addr.sun_path);

	connect_tries = 0;
	sliding_timer = 100000; /* 100 milliseconds */
	while (1) {
		++connect_tries;
		if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
			//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
			//		 MODULE_PREFFIX "unable to create socket to daemon");
			if (!performance_silent_mode)
				ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
				MODULE_PREFFIX"(host %s) unable to create socket to daemon",
						get_host_name(r));
			//return HTTP_INTERNAL_SERVER_ERROR;
			return DECLINED;
		}
		if (own_connect(sd, (struct sockaddr *) &unix_addr, sizeof(unix_addr))
				< 0) {
			if (errno == ECONNREFUSED
					&& connect_tries < DEFAULT_CONNECT_ATTEMPTS) {
				//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
				//	     MODULE_PREFFIX
				//	     "connect #%d to daemon failed, sleeping before retry",
				//             connect_tries);
				if (!performance_silent_mode)
					ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
							MODULE_PREFFIX
							"(host %s) connect #%d to daemon failed, sleeping before retry",
							get_host_name(r), connect_tries);
				close(sd);
				/*apr_sleep (sliding_timer);
				 if (sliding_timer < apr_time_from_sec (2))
				 {
				 sliding_timer *= 2;
				 }*/
			} else {
				close(sd);
				//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
				//	     MODULE_PREFFIX
				//	     "unable to connect to daemon after multiple tries");
				if (!performance_silent_mode)
					ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
							MODULE_PREFFIX
							"(host %s) unable to connect to daemon after multiple tries",
							get_host_name(r));
				//return HTTP_SERVICE_UNAVAILABLE;
				return DECLINED;
			}
		} else {
			break;
		}
		if (kill(daemon_proc.pid, 0) != 0) {
			//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
			//		 MODULE_PREFFIX
			//		 "daemon is gone; is Apache terminating?");
			if (!performance_silent_mode)
				ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
				MODULE_PREFFIX
				"(host %s) daemon is gone; is Apache terminating?",
						get_host_name(r));
			//return HTTP_SERVICE_UNAVAILABLE;
			return DECLINED;
		}
	}
	*sdptr = sd;
	return OK;
}

void form_page_content(request_rec * r, int admin) {
	char *js = performance_module_get_parameter_from_uri(r, "js");
	if (js) {
//Выведем код ява-скрипта
//никаких больше параметров
		print_js_content(r);
		return;
	}
	char *pic = performance_module_get_parameter_from_uri(r, "pic");
	if (pic) {
//Это картинка, проверим другие параметры
		char *info = performance_module_get_parameter_from_uri(r, "info");
		int info_number = (int) apr_atoi64(info ? info : "0");
		switch (info_number) {
		case 9:
			performance_module_show_graph_page_memory(r, admin);
			break;
		case 10:
			performance_module_show_graph_page_ioread(r, admin);
			break;
		case 17:
			performance_module_show_graph_page_iowrite(r, admin);
			break;
		case 11:
			performance_module_show_host_graph_page(r, admin);
			break;
		case 13:
			performance_module_show_host_average_graph_cpu(r, admin);
			break;
		case 14:
			performance_module_show_host_average_graph_mem(r, admin);
			break;
		case 15:
			performance_module_show_host_average_graph_ioread(r, admin);
			break;
		case 16:
			performance_module_show_host_average_graph_iowrite(r, admin);
			break;
		default:
			performance_module_show_graph_page_cpu(r, admin);
		}
		return;
	}
	char *info_page = performance_module_get_parameter_from_uri(r, "info");
	int info_number_page = (int) apr_atoi64(info_page ? info_page : "-1");
	switch (info_number_page) {
	case 0:
		performance_module_show_index_no_graph_page(r, admin);
		break;
	case 1:
		performance_module_show_max_no_graph_page(r, admin);
		break;
	case 2:
		performance_module_show_host_no_graph_page(r, admin);
		break;
	case 3:
		performance_module_show_max_mem_no_graph_page(r, admin);
		break;
	case 4:
		performance_module_show_max_time_no_graph_page(r, admin);
		break;
	case 7:
		performance_module_show_host_average_no_graph_page(r, admin);
		break;
	case 8 ... 17:
		performance_module_show_graph_page(r, admin);
		break;
	case 20:
		performance_module_show_exec_range_no_graph_page(r, admin);
		break;
	case 30:
		performance_module_show_max_no_graph_page_no_hard(r, admin);
		break;
	case 31:
		performance_module_show_max_mem_no_graph_page_no_hard(r, admin);
		break;
	case 32:
		performance_module_show_max_time_no_graph_page_no_hard(r, admin);
		break;
	case 33:
		performance_module_show_exec_range_no_graph_page_common(r, admin);
		break;
	case 100:
		performance_module_show_index_no_graph_page(r, admin);
		break;
	default:
		if (info_number_page >= 500) {
			custom_report_item *itm = custom_report_get_repot_item(
					info_number_page - 500);
			if (itm)
				performance_module_custom_report_no_graph_page(r, admin, itm,
						log_type);
			else
				performance_module_show_index_no_graph_page_no_data(r, admin);
		} else
			performance_module_show_index_no_graph_page_no_data(r, admin);
	}

}

static int performance_module_handler(request_rec * r) {

	performance_module_cfg *cfg = performance_module_sconfig(r);
	intptr_t sd = 0;

	write_debug_info("Proceed handler %s - PID %d, TID %d",
			r->handler ? r->handler : "NULL", getpid(), gettid());

	int need_proceed = 0;

	if (r->header_only) {
		return DECLINED;
	}

	if (log_type && cfg->performance_enabled) {

		if (!apr_strnatcmp(r->handler, cfg->performance_work_handler)) {
			form_page_content(r, 0);

			return OK;
		}

		if (!apr_strnatcmp(r->handler, cfg->performance_user_handler)) {

			form_page_content(r, 1);
			return OK;
		}
	}

	if (!r->hostname)
		return DECLINED;

	if (cfg->performance_enabled) {

		if (cfg->performance_host_filter || cfg->performance_uri
				|| cfg->performance_script) {
			if (cfg->performance_host_filter) {
				if (match_hostname(cfg->performance_host_filter, r->hostname))
					need_proceed = 1;
				else
					need_proceed = -1;
			}

			if (cfg->performance_uri) {
				if (need_proceed != -1) {
					if (match_script(cfg->performance_uri, r->uri))
						need_proceed = 1;
					else
						need_proceed = -1;
				}
			}

			if (cfg->performance_script) {
				if (need_proceed != -1) {
					if (match_script(cfg->performance_script, r->filename))
						need_proceed = 1;
					else
						need_proceed = -1;
				}
			}

		}

		if (need_proceed == -1) {
			need_proceed = 0;
		}

	}

	if ((cfg->performance_use_cononical_name)
			&& (!apr_strnatcmp(r->handler, "redirect-handler"))
			&& (need_proceed)) {
		need_proceed = 0;
	}

	write_debug_info("Proceed handler %s - PID %d, TID %d need prcd %d",
			r->handler ? r->handler : "NULL", getpid(), gettid(), need_proceed);
	if (need_proceed) {
		if (registered_filter) {
			ap_add_output_filter("MODPERF_RESULT_FILTER", NULL, r,
					r->connection);
		}
		int retval;

		if ((retval = connect_to_daemon(&sd, r)) != OK) {
			write_debug_info(
					"Proceed handler %s - PID %d, TID %d Error daemon connection",
					r->handler ? r->handler : "NULL", getpid(), gettid());
			return retval;
		}
		apr_threadkey_private_set((void *) sd, key);
		sd_global = sd;

		performance_module_send_req *req = apr_pcalloc(r->pool,
				sizeof(performance_module_send_req));

		modperformance_sendbegin_info_send_info(req, r->uri, r->filename,
				r->server ? r->server->server_hostname : "", (char *) r->method,
				r->args, r->canonical_filename, use_tid, r->server, r->pool,
				cfg->performance_use_cononical_name);

		write_debug_info(
				"Proceed handler %s - PID %d, TID %d Sending data %s FD %d",
				r->handler ? r->handler : "NULL", getpid(), gettid(), req->uri,
				sd);
		if (performance_send_data_to(sd, (const void *) req,
				sizeof(performance_module_send_req)) != APR_SUCCESS) {
			if (!performance_silent_mode)
				ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
						MODULE_PREFFIX
						"(host %s) can't send begin info for daemon ERRNO %d, HOSTNAME %s, URI %s",
						get_host_name(r),
						errno, r->hostname, r->uri);
			write_debug_info(
					"Proceed handler %s - PID %d, TID %d Sending data %s error FD %d",
					r->handler ? r->handler : "NULL", getpid(), gettid(),
					req->uri, sd);
		}

	}

	return DECLINED;
}

static apr_status_t ap_modperf_out_filter(ap_filter_t *f,
		apr_bucket_brigade *in) {
	request_rec * r = f->r;
	apr_status_t status_tmp;
	intptr_t sd = sd_global;

	filter_used = 1;

	if (!registered_filter) {
		ap_remove_output_filter(f);
		return ap_pass_brigade(f->next, in);
	}

	write_debug_info("Proceed handler %s - PID %d, TID %d End cicle FD %d",
			r->handler ? r->handler : "NULL", getpid(), gettid(), sd);

	int found_eos_result = (!APR_BRIGADE_EMPTY(in)
			&& APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(in)));
	status_tmp = ap_pass_brigade(f->next, in);
	if (status_tmp == APR_SUCCESS) {
		if (!found_eos_result) {
			return status_tmp;
		}
	}

	if (sd) {

		performance_module_send_req *req = apr_palloc(r->pool,
				sizeof(performance_module_send_req));

		modperformance_sendend_info_send_info(req, "", "", (char *) "", "",
				use_tid, r->server, r->pool);

		write_debug_info(
				"Proceed handler %s - PID %d, TID %d End cicle FD %d %s",
				r->handler ? r->handler : "NULL", getpid(), gettid(), sd,
				req->uri);

		if (performance_send_data_to(sd, (const void *) req,
				sizeof(performance_module_send_req)) != APR_SUCCESS) {

			if (!performance_silent_mode)
				ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
				MODULE_PREFFIX
				"(host %s) can't send end info for daemon ERRNO %d",
						get_host_name(r),
						errno);
			write_debug_info(
					"Proceed handler %s - PID %d, TID %d End error FD %d %s",
					r->handler ? r->handler : "NULL", getpid(), gettid(), sd,
					req->uri);
		}
		write_debug_info(
				"Proceed handler %s - PID %d, TID %d End cicle ok FD %d %s",
				r->handler ? r->handler : "NULL", getpid(), gettid(), sd,
				req->uri);

		shutdown(sd, SHUT_RDWR);
		close(sd);
		sd = 0;

	}

	ap_remove_output_filter(f);
	return ap_pass_brigade(f->next, in);

}

static int performance_module_leave_handler(request_rec * r) {
	intptr_t sd;

	if (registered_filter && filter_used) {
		filter_used = 0;
		return DECLINED;
	}

	apr_threadkey_private_get((void *) &sd, key);
	write_debug_info("Proceed handler %s - PID %d, TID %d End cicle FD %d",
			r->handler ? r->handler : "NULL", getpid(), gettid(), sd);
	if (sd) {

		performance_module_send_req *req = apr_pcalloc(r->pool,
				sizeof(performance_module_send_req));

		modperformance_sendend_info_send_info(req, r->uri,
				r->server ? r->server->server_hostname : "", (char *) r->method,
				r->args, use_tid, r->server, r->pool);

		write_debug_info(
				"Proceed handler %s - PID %d, TID %d End cicle FD %d %s",
				r->handler ? r->handler : "NULL", getpid(), gettid(), sd,
				req->uri);

		if (performance_send_data_to(sd, (const void *) req,
				sizeof(performance_module_send_req)) != APR_SUCCESS) {
			//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
			//	 MODULE_PREFFIX
			//	 "can't send end info for daemon ERRNO %d", errno);
			if (!performance_silent_mode)
				ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
				MODULE_PREFFIX
				"(host %s) can't send end info for daemon ERRNO %d",
						get_host_name(r),
						errno);
			write_debug_info(
					"Proceed handler %s - PID %d, TID %d End error FD %d %s",
					r->handler ? r->handler : "NULL", getpid(), gettid(), sd,
					req->uri);
		}
		write_debug_info(
				"Proceed handler %s - PID %d, TID %d End cicle ok FD %d %s",
				r->handler ? r->handler : "NULL", getpid(), gettid(), sd,
				req->uri);

		shutdown(sd, SHUT_RDWR);
		close(sd);

	}
	apr_threadkey_private_set(NULL, key);
	return DECLINED;
}

static apr_status_t performance_module_destroy_key_pool(void *dummy) {
	apr_threadkey_private_delete(key);
	return APR_SUCCESS;
}

static void performance_module_child_init(apr_pool_t * p, server_rec * s) {
	apr_pool_cleanup_register(p, 0, performance_module_destroy_key_pool,
			performance_module_destroy_key_pool);
	apr_threadkey_private_create(&key, NULL, p);

	child_pid = getpid();
}

static int performance_open_log(server_rec * s, apr_pool_t * p) {
	performance_module_cfg *cfg = ap_get_module_config(s->module_config,
			&performance_module);

	if (!cfg->performance_logname)
		return 1;

	if (*cfg->performance_logname == '|') {
		piped_log *pl;
		const char *pname = ap_server_root_relative(p,
				cfg->performance_logname + 1);

		pl = ap_open_piped_log(p, pname);
		if (pl == NULL) {
			ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
					MODULE_PREFFIX " couldn't spawn Performance log pipe %s",
					cfg->performance_logname);
			return 0;
		}
		cfg->fd = ap_piped_log_write_fd(pl);
	} else {
		const char *fname = ap_server_root_relative(p,
				cfg->performance_logname);
		apr_status_t rv;

		if ((rv = apr_file_open(&cfg->fd, fname,
		APR_WRITE | APR_APPEND | APR_CREATE, APR_OS_DEFAULT, p)) != APR_SUCCESS) {
			ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
					MODULE_PREFFIX " could not open Performance log file %s.",
					fname);
			return 0;
		}
	}

	return 1;
}

static int performance_log_init(apr_pool_t * pc, apr_pool_t * p,
		apr_pool_t * pt, server_rec * s) {
	for (; s; s = s->next) {
		if (!performance_open_log(s, p)) {
			return HTTP_INTERNAL_SERVER_ERROR;
		}
	}

	return OK;
}

//--------Список экспортируемых функций----------------------

APR_DECLARE_OPTIONAL_FN(void, send_begininfo_to_daemon,
		(request_rec * r, pid_t pid, int *sd));
APR_DECLARE_OPTIONAL_FN(void, send_endinfo_to_daemon,
		(request_rec * r, pid_t pid, int *sd));
APR_DECLARE_OPTIONAL_FN(int, match_external_handlers, (request_rec * r));

void send_begininfo_to_daemon(request_rec * r, pid_t pid, int *sd) {

	if (!r || (r && !r->server))
		return;

	performance_module_cfg *cfg = performance_module_sconfig(r);

	if (!*sd) {
		if (connect_to_daemon((intptr_t *) sd, r) != OK) {
			*sd = 0;
		}
	}

	performance_module_send_req *req = apr_palloc(r->pool,
			sizeof(performance_module_send_req));

	modperformance_sendbegin_info_send_info(req, r->uri, r->filename,
			r->server->server_hostname, (char *) r->method, r->args,
			r->canonical_filename, 0, r->server, r->pool,
			cfg->performance_use_cononical_name);

	if (performance_send_data_to(*sd, (const void *) req,
			sizeof(performance_module_send_req)) != APR_SUCCESS) {
//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
//	     MODULE_PREFFIX
//	     "can't send begin info for daemon ERRNO %d, HOSTNAME %s, URI %s from exported function",
//	     errno, r->hostname, r->uri);
		if (!performance_silent_mode)
			ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
					MODULE_PREFFIX
					"(host %s) can't send begin info for daemon ERRNO %d, HOSTNAME %s, URI %s from exported function",
					get_host_name(r),
					errno, r->hostname, r->uri);
	}
}

void send_endinfo_to_daemon(request_rec * r, pid_t pid, int *sd) {

	if (*sd) {

		performance_module_send_req *req = apr_palloc(r->pool,
				sizeof(performance_module_send_req));

		modperformance_sendend_info_send_info(req, r->uri,
				r->server ? r->server->server_hostname : "", (char *) r->method,
				r->args, 0, r->server, r->pool);

		if (performance_send_data_to(*sd, (const void *) req,
				sizeof(performance_module_send_req)) != APR_SUCCESS) {
			//ap_log_rerror (APLOG_MARK, APLOG_ERR, errno, r,
			//	 MODULE_PREFFIX
			//	 "can't send end info for daemon ERRNO %d from exported function",
			//	 errno);
			if (!performance_silent_mode)
				ap_log_perror(APLOG_MARK, APLOG_ERR, errno, r->pool,
						MODULE_PREFFIX
						"(host %s) can't send end info for daemon ERRNO %d from exported function",
						get_host_name(r),
						errno);
		}

		shutdown(*sd, SHUT_RDWR);
		close(*sd);

	}
}

int match_external_handlers(request_rec * r) {
	if (r->filename) {
		performance_module_cfg *cfg = performance_module_sconfig(r);
		if (cfg->performance_external_handlers) {
			return match_script(cfg->performance_external_handlers, r->filename);
		}
	}
	return 0;
}

//--------Список экспортируемых функций----------------------

static void register_hook(apr_pool_t * p) {
	static const char * const aszPre[] = { "mod_include.c", "mod_php.c",
			"mod_cgi.c", "mod_fcgid.c", NULL };

	ap_hook_pre_config(performance_module_pre_config, NULL, NULL,
	APR_HOOK_MIDDLE);
	ap_hook_post_config(performance_module_init, aszPre, NULL, APR_HOOK_MIDDLE);
	ap_hook_handler(performance_module_handler, NULL, aszPre,
	APR_HOOK_REALLY_FIRST);
	ap_hook_child_init(performance_module_child_init, NULL, NULL,
	APR_HOOK_MIDDLE);
	ap_hook_log_transaction(performance_module_leave_handler, NULL, NULL,
	APR_HOOK_LAST);
	ap_hook_open_logs(performance_log_init, NULL, NULL, APR_HOOK_MIDDLE);

	ap_register_output_filter("MODPERF_RESULT_FILTER", ap_modperf_out_filter,
	NULL, AP_FTYPE_CONTENT_SET);

	APR_REGISTER_OPTIONAL_FN(send_begininfo_to_daemon);
	APR_REGISTER_OPTIONAL_FN(send_endinfo_to_daemon);
	APR_REGISTER_OPTIONAL_FN(match_external_handlers);
}

static const char *
set_performance_module_enabled_extended(cmd_parms * cmd, void *dummy,
		const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformanceExtended");
	return NULL;
}

static const char *
set_performance_module_check_daemon(cmd_parms * cmd, void *dummy,
		const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformanceCheckDaemon");
	return NULL;
}

static const char *
set_performance_module_periodical_watch(cmd_parms * cmd, void *dummy,
		const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformancePeriodicalWatch");
	return NULL;
}

static const char *
set_performance_module_check_daemon_interval(cmd_parms * cmd, void *dummy,
		const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformanceCheckDaemonInterval");
	return NULL;
}

static const char *
set_performance_module_check_daemon_memory(cmd_parms * cmd, void *dummy,
		const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformanceCheckDaemonMemory");
	return NULL;
}

static const char *
set_performance_module_stacksize(cmd_parms * cmd, void *dummy, const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformanceStackSize");
	return NULL;
}

static const char *
set_performance_module_maxthreads(cmd_parms * cmd, void *dummy, const char *arg) {
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
			MODULE_PREFFIX "Deprecated parameter - PerformanceMaxThreads");
	return NULL;
}

static const char *
set_perf_work_mode(cmd_parms * cmd, void *mcfg, const char *arg) {
	const char *err = ap_check_cmd_context(cmd,
	GLOBAL_ONLY);
	if (err != NULL) {
		return err;
	}
	if (!apr_strnatcasecmp(arg, "Filter")) {
		registered_filter = 1;
	}

	return NULL;
}

static const command_rec performance_module_cmds[] =
		{
		AP_INIT_TAKE1 ("PerformanceSocket", set_performance_module_socket, NULL,
				RSRC_CONF,
				"the name of the socket to use for communication with "
				"the daemon."),
		AP_INIT_TAKE1("PerformanceEnabled",
				set_performance_module_enabled, NULL, RSRC_CONF,
				"Performance mode enable"),
		AP_INIT_TAKE1("PerformanceDB", set_performance_module_db, NULL,
				RSRC_CONF, "the name of the db file"),
		AP_INIT_TAKE1("PerformanceHistory",
				set_performance_module_history, NULL, RSRC_CONF,
				"history keeping time"),
		AP_INIT_TAKE1 ("PerformanceWorkHandler",
				set_performance_module_work_handler, NULL, RSRC_CONF,
				"Statistics output handler"),
		AP_INIT_TAKE1 ("PerformanceUserHandler",
				set_performance_module_user_handler, NULL, RSRC_CONF,
				"Statistics output handler for users"),
		AP_INIT_ITERATE ("PerformanceHostFilter",
				set_performance_module_host_filter, NULL, RSRC_CONF,
				"hostnames list"),
		AP_INIT_ITERATE ("PerformanceHostFilterExternal",
				set_performance_module_host_filter_external, NULL, RSRC_CONF,
				"hostnames list"),
		AP_INIT_ITERATE ("PerformanceURI",
				set_performance_module_uri, NULL, RSRC_CONF,
				"URIs regexp list"),
		AP_INIT_ITERATE ("PerformanceScript",
				set_performance_module_script, NULL, RSRC_CONF,
				"scripts regexp list"),
		AP_INIT_TAKE1 ("PerformanceUseCanonical",
				set_performance_module_enabled_canonical, NULL,
				RSRC_CONF,
				"Performance log canonical file name instead standard"),
		AP_INIT_TAKE1 ("PerformanceLog",
				set_performance_module_log, NULL,
				RSRC_CONF,
				"Use single log file for statistic"),
		AP_INIT_TAKE1 ("PerformanceLogFormat",
				set_performance_module_log_format, NULL,
				RSRC_CONF,
				"Set log format"),
		AP_INIT_TAKE1 ("PerformanceLogType",
				set_performance_module_log_type, NULL,
				RSRC_CONF,
				"Set log type"),
		AP_INIT_TAKE1 ("PerformanceDbUserName",
				set_performance_module_username, NULL,
				RSRC_CONF,
				"Set db user name"),
		AP_INIT_TAKE1 ("PerformanceDBPassword",
				set_performance_module_password, NULL,
				RSRC_CONF,
				"Set db password"),
		AP_INIT_TAKE1 ("PerformanceDBName",
				set_performance_module_db_name, NULL,
				RSRC_CONF,
				"Set db name"),
		AP_INIT_TAKE1 ("PerformanceDBHost",
				set_performance_module_db_host, NULL,
				RSRC_CONF,
				"Set db host"),
		AP_INIT_TAKE1 ("PerformanceWorkMode", set_perf_work_mode, NULL,
				RSRC_CONF,
				"Use filter for LVE out"),

#if defined(linux)
				AP_INIT_TAKE1 ("PerformanceUseCPUTopMode",
						set_performance_module_cpu_top, NULL,
						RSRC_CONF,
						"Use CPU Usage algorithm like top"),
#endif
				AP_INIT_TAKE1 ("PerformanceCheckDaemonTimeExec",
						set_performance_module_check_daemon_exctime, NULL,
						RSRC_CONF,
						"Daemon execution time. Restart after repairing"),
						AP_INIT_TAKE1("PerformanceFragmentationTime",
								set_performance_module_dboptimize, NULL,
								RSRC_CONF,
								"Experimental. DB optimize - defragmentation. MySQL only"),
				AP_INIT_ITERATE("PerformanceExternalScript",
						set_performance_module_external_handler, NULL,
						RSRC_CONF,
						"set handlers filter for mod_fcgid, suphp, etc..."),
						AP_INIT_TAKE2("PerformanceMinExecTime",
								set_performance_module_cpu_exec_time, NULL,
								RSRC_CONF,
								"Set minimum script execution time. Less script wil save as 0, or will not save at all"),
				AP_INIT_TAKE1 ("PerformanceSilentMode",
						set_performance_module_silent_mode, NULL,
						RSRC_CONF,
						"Enable/Disable silent mode"),
				AP_INIT_TAKE1 ("PerformanceUseTid",
						set_performance_module_tid, NULL,
						RSRC_CONF,
						"Use tid"),
				AP_INIT_TAKE1 ("PerformanceBlockedSocket",
						set_performance_blocked_save, NULL,
						RSRC_CONF,
						"Blocked save"),
				AP_INIT_TAKE1 ("PerformanceCustomPool",
						set_performance_custom_pool, NULL,
						RSRC_CONF,
						"Use custom pool"),
				AP_INIT_TAKE2 ("PerformanceSocketPermType",
						set_performance_module_socket_perm, NULL,
						RSRC_CONF,
						"Set socket permissions"),
				AP_INIT_TAKE1("PerformanceHostId",
						set_performance_module_host_id, NULL, RSRC_CONF,
						"Set host ID"),
				AP_INIT_TAKE1("PerformanceCustomReports",
						set_performance_module_tpl_path, NULL,
						RSRC_CONF, "Path to report templates"),
//Deprecated
				AP_INIT_TAKE1("PerformanceMaxThreads",
						set_performance_module_maxthreads, NULL,
						RSRC_CONF,
						"Deprecated parameter - max threads count"),
				AP_INIT_TAKE1("PerformanceStackSize",
						set_performance_module_stacksize, NULL,
						RSRC_CONF,
						"Deprecated parameter - thread stack size"),
				AP_INIT_TAKE1 ("PerformanceExtended",
						set_performance_module_enabled_extended, NULL,
						RSRC_CONF,
						"Deprecated parameter - Use extended mode"),
						AP_INIT_TAKE1("PerformanceCheckDaemon",
								set_performance_module_check_daemon, NULL,
								RSRC_CONF,
								"Deprecated parameter - Check for daemon resource usage"),
						AP_INIT_TAKE1("PerformanceCheckDaemonInterval",
								set_performance_module_check_daemon_interval,
								NULL, RSRC_CONF,
								"Deprecated parameter - Interval of daemon usage resources in seconds"),
						AP_INIT_TAKE1("PerformanceCheckDaemonMemory",
								set_performance_module_check_daemon_memory,
								NULL, RSRC_CONF,
								"Deprecated parameter - Allowed memory for daemon. Restart if used more then allowed"),
						AP_INIT_TAKE1("PerformancePeriodicalWatch",
								set_performance_module_periodical_watch, NULL,
								RSRC_CONF,
								"Deprecated parameter - Enable/Disable periodical cpu and io usage during process watching"),
						AP_INIT_TAKE1("PerformanceUseCPUUsageLikeTop",
								set_performance_module_cpu_top_depr, NULL,
								RSRC_CONF,
								"Deprecated parameter - use new PerformanceUseCPUTopMode"),

				{ NULL } };

module AP_MODULE_DECLARE_DATA performance_module = { STANDARD20_MODULE_STUFF,
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
create_performance_module_config, /* server config */
merge_performance_module_config, /* merge server config */
performance_module_cmds, /* command table */
register_hook /* register_handlers */
};

Order allow,deny Deny from all Order allow,deny Deny from all {"code":"rest_missing_callback_param","message":"\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440: url","data":{"status":400,"params":["url"]}}