Лог запросов MySQL средствами Wordpress

absurdo
На сайте с 28.11.2006
Offline
77
3214

Подскажите пожалуйста, как получить лог запросов MySQL средствами Wordpress?

Нужны запросы за определенный период, например сутки.

Как увидеть список запросов при генерации конкретной страницы понятно. Но нужно отследить что именно создает нагрузку на сервер БД.

Так как сайт на разделяемом хостинге, то включить лог медленных запросов возможности нет.

TF-Studio
На сайте с 17.08.2010
Offline
334
#1

никак.

если все логировать самому- нагрузка только вырастет.

Поставьте дома, сделайте тестовую нагрузку и смотрите что и как.

Всё ещё лучший способ заработка для белых сайтов: GoGetLinks (https://www.gogetlinks.net/?inv=fahbn8).
absurdo
На сайте с 28.11.2006
Offline
77
#2
TF-Studio:
никак.
если все логировать самому- нагрузка только вырастет.
Поставьте дома, сделайте тестовую нагрузку и смотрите что и как.

Конечно нагрузка вырастет.

Но мне нужно знать что происходит с БД в реальных условиях.

Все закешировано, несмотря на это запросов к БД много.

Интересно знать что именно создает эти запросы.

ДП
На сайте с 23.11.2009
Offline
203
#3

Я так думаю, что WP использует какую-то свою обертку для доступа к БД. Вот расковырять этот класс и обернуть место собюственно выполнения запросов таймером и логированием - в общем случае так.

Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#4

/includes/wp-db.php


function query( $query ) {
if ( ! $this->ready )
return false;

// some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
$query = apply_filters( 'query', $query );

$return_val = 0;
$this->flush();

// Log how the function was called
$this->func_call = "\$db->query(\"$query\")";

// Keep track of the last query for debug..
$this->last_query = $query;

if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
$this->timer_start();

$this->result = @mysql_query( $query, $this->dbh );
$this->num_queries++;

if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
$this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );

// If there is an error then take note of it..
if ( $this->last_error = mysql_error( $this->dbh ) ) {
$this->print_error();
return false;
}

if ( preg_match( '/^\s*(create|alter|truncate|drop) /i', $query ) ) {
$return_val = $this->result;
} elseif ( preg_match( '/^\s*(insert|delete|update|replace) /i', $query ) ) {
$this->rows_affected = mysql_affected_rows( $this->dbh );
// Take note of the insert_id
if ( preg_match( '/^\s*(insert|replace) /i', $query ) ) {
$this->insert_id = mysql_insert_id($this->dbh);
}
// Return number of rows affected
$return_val = $this->rows_affected;
} else {
$i = 0;
while ( $i < @mysql_num_fields( $this->result ) ) {
$this->col_info[$i] = @mysql_fetch_field( $this->result );
$i++;
}
$num_rows = 0;
while ( $row = @mysql_fetch_object( $this->result ) ) {
$this->last_result[$num_rows] = $row;
$num_rows++;
}

@mysql_free_result( $this->result );

// Log number of rows the query returned
// and return number of rows selected
$this->num_rows = $num_rows;
$return_val = $num_rows;
}

return $return_val;
}

Нас интересует строка


$this->result = @mysql_query( $query, $this->dbh );

Перед ней пишем


$time = microtime(1);

после нее


$this->times[] = (microtime(1)-$time);

В итоге получаем


$time = microtime(1);
$this->result = @mysql_query( $query, $this->dbh );
self::queriesTime[$this->num_queries]['time'] = (microtime(1)-$time);
self::queriesTime[$this->num_queries]['query'] =$query;
$this->num_queries++;//строка долна идти после получения времени

В начале класса объявляем свойство queriesTime, которое является массивом.


private static $queriesTime = array();

То есть это на выходе получиться массив, где в каждой ячейки будет лежать еще 2 ячейки со временем запроса, и с самим запросом.

Теперь создадим метод, который будет все это дело логировать.


public static function myCustomLoger()
{
$output = '';
foreach(self::queriesTime as $k=>$v)
{
$time = $v['time'];
$query = $v['query'];
//Я запишу все это дело в файл
$output .= "$time<qtdelimiter>$query<linesdelimiter>";
}
$fileName = $_SERVER['DOCUMENT_ROOT'] .'/mylogs/' .date('Y-m-d', time()) .'.log';//название файла - текущая дата формата ГГГГ-ММ-ДД, то есть для каждых суток создается отдельный файл.
file_put_contents($fileName, $output, FILE_APPEND);
}

Ну и финал. В конце файла index.php(можно еще к админке прикрутить) вызываем наш метод myCustomLoger.


$wpdb->myCustomLoger();

Я писал в файл, так как это дело быстрей записи в БД. При желании можно сделать скрипт, который по крону в начале новых суток обработает файл с логами за прошедшие сутки и запишет данные в БД. Ну а дальше уже можно написать интерфейс для работы с логами из БД.

Помимо время запроса и текста запроса можно добавить тип запроса(селект, инсерт, делит, апдейт), количество символов в запросе, страницу, где выполняется запрос и т.д. Вообщем все что захотите.

Если интересуют только медленные запросы, то надо так:


$time = microtime(1);
$this->result = @mysql_query( $query, $this->dbh );
$time = (microtime(1)-$time);
if ($time > 0.5)
{
self::queriesTime[$this->num_queries]['time'] = $time;
self::queriesTime[$this->num_queries]['query'] = $query;
}
$this->num_queries++;//строка долна идти после получения времени

0.5 - время в секундах, то есть если наш запрос выполнялся дольше 500 милисекунд, то мы его записываем

ЗЫ. многа букав получилось, уж извиняйте:)

Подпись))

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий