Захотелось сделать свой собственный счетчик посетителей и хитов для своего сайта генерируемого Hugo для темы HBS. Собирать счетчик буду на основе логов веб сервера, обработанных GoAccess. Будет добавлен блок в боковую панель сайта со статистикой в виде смешанного графика количества посетителей за 30 дней.
Конфиг GoAccess
Краткий конфиг без лишней воды, только то что надо без всяких пояснений. Если нужны данные расшифровки строк конфига их можно прочитать тут - файл конфигурации goaccess. Поэтому создадим конфиг, который будет формировать краткий отчет, без лишних параметров.
sudo nano /etc/goaccess/stat-wildserver.ru.conf
Вставить данные опции:
######################################
# Опции формата времени (обязательно)
######################################
time-format %H:%M:%S
######################################
# Опции формата даты (обязательно)
######################################
date-format %d/%b/%Y
######################################
# Опции формата логов
######################################
log-format COMBINED
######################################
config-dialog false
hl-header true
json-pretty-print false
no-color false
no-column-names false
no-csv-summary false
no-progress false
no-tab-scroll false
with-mouse false
agent-list false
with-output-resolver false
# Написать например IP адреса своих устройств, чтобы не учитывались ваши заходы
#exclude-ip 127.0.0.1
#exclude-ip 192.168.0.1-192.168.0.100
http-method yes
http-protocol yes
no-query-string false
no-term-resolver false
444-as-404 false
4xx-to-unique-count false
all-static-files false
# Включить дополнительный разделенный список браузеров/краулеров/ленточек и т.д.
# См. config/browsers.list для примера или
# https://raw.githubusercontent.com/allinurl/goaccess/master/config/browsers.list
#
#browsers-file <filename>
double-decode false
ignore-crawlers true
crawlers-only false
unknowns-as-crawlers false
# Игнорировать парсинг и отображение указанной панели.
#ignore-panel VISITORS
ignore-panel REQUESTS
ignore-panel REQUESTS_STATIC
ignore-panel NOT_FOUND
ignore-panel HOSTS
ignore-panel OS
ignore-panel BROWSERS
ignore-panel VISIT_TIMES
ignore-panel VIRTUAL_HOSTS
ignore-panel REFERRERS
ignore-panel REFERRING_SITES
ignore-panel KEYPHRASES
ignore-panel STATUS_CODES
ignore-panel REMOTE_USER
ignore-panel CACHE_STATUS
ignore-panel GEO_LOCATION
ignore-panel MIME_TYPE
ignore-panel TLS_TYPE
Сохраняем файл Ctrl+O , Enter, и закрываем Ctrl+X
Логи сайта
Ранее перенес логи сайта в отдельный каталог для удобства их ротации. Что бы можно было регулировать необходимый промежуток времени хранения логов для последующего формирования отчетов. Про это писал тут - ротация логов для конкретного сайта на примере apache2
Создание отчета по сайту
Создать исполняемый файл nano ~/stat/create-report-wildserver.ru.sh
, который будет запускаться например раз в час для объединения всех логов даже которые заархивированы logrotate. После обрабатываться GoAccess, который сформирует файл статистики в формате .json
, для более удобной обработки и передачи на сайт.
#!/bin/bash
# Пути к файлам логов и отчету с конфигом
LOG_DIR="/var/log/apache2/wildserver.ru"
ALL_LOG="/home/USER/stat/wildserver.ru.access.log"
REPORT="/home/USER/wwww/wildserver.ru/stat/stat.json"
CONFIG="/etc/goaccess/stat-wildserver.ru.conf"
# Создание или очистка общего файла логов
> $ALL_LOG
# Объединение всех файлов логов (обычных и архивированных) в один
# Добавление обычного лог-файла
cat $LOG_DIR/wildserver.ru.access.log >> $ALL_LOG
# Добавление дневного лога
cat $LOG_DIR/wildserver.ru.access.log.1 >> $ALL_LOG
# Добавление всех архивов
for file in $LOG_DIR/wildserver.ru.access.log.*.gz; do
if [ -f "$file" ]; then
zcat "$file" >> $ALL_LOG
fi
done
# Создание HTML-отчета GoAccess
goaccess $ALL_LOG -o $REPORT --json -p $CONFIG
# Изменение прав на отчет для пользователя USER и группы www-data
chown USER:www-data $REPORT
Сохраняем файл Ctrl+O , Enter, и закрываем Ctrl+X
Сделать скрипт исполняемым:
chmod +x ~/stat/create-report-wildserver.ru.sh
Добавить задачу в сron
Файл должен исполняться от имени root
sudo crontab -e
0 * * * * /home/USER/stat/create-report-wildserver.ru.sh
Скрипт будет запускаться каждый час.
Вставка кода статистики в сайт
Открыть проект с сайтом в Visual Studio Code создать пользовательский файл layouts/partials/sidebar/profile.html
в котором добавим блок сайдбара с графиком посещения пользователей в стиле темы HBS:
{{- $author := site.Params.author }}
{{- with site.Author }}
{{- $author = . }}
{{- warnf "The author key in site configuration is deprecated. Use params.author instead." }}
{{- end }}
{{- if $author }}
{{- $layout := default "" $author.params.layout }}
{{- if eq $layout "compact" }}
{{- partial "sidebar/profile/compact" . }}
{{- else }}
{{- partial "sidebar/profile/default" . }}
{{- end }}
{{- end }}
{{- $collapsed := default false .Site.Params.sidebar.collapsed }}
<div class="accordion statistics">
<section class="row card component">
<div class="card-header">
<h4 class="card-title text-surface">
<span>Статистика за 30 дней</span>
</h4>
<a
class="accordion-button d-lg-none mb-1 shadow-none p-0 bg-transparent{{ if $collapsed }} collapsed{{ end }}"
role="button" data-bs-toggle="collapse" href="#statistics" aria-expanded="{{ if $collapsed }}false{{ else }}true{{ end }}" aria-controls="statistics">
Статистика
</a>
</div>
<div class="card-body collapse accordion-collapse accordion-body d-lg-block{{ if not $collapsed }} show{{ end }}" id="statistics">
<!-- Блок для графика -->
<canvas id="statsChart" width="800" height="300"></canvas>
</div>
</section>
</div>
<!-- Интеграция Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
fetch('/stat/stat.json') // Обновите путь до статического JSON
.then(response => {
if (!response.ok) {
throw new Error('Сетевая ошибка: ' + response.status);
}
return response.json();
})
.then(data => {
// Сортируем даты от более ранних к более поздним
const entries = data.visitors.data.sort((a, b) => {
const dateA = new Date(a.data.slice(0, 4), a.data.slice(4, 6) - 1, a.data.slice(6, 8));
const dateB = new Date(b.data.slice(0, 4), b.data.slice(4, 6) - 1, b.data.slice(6, 8));
return dateA - dateB;
});
// Функция для получения сокращенного названия дня недели
const getDayShortName = (date) => {
const days = ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'];
return days[date.getDay()];
};
const labels = entries.map(entry => {
const date = new Date(entry.data.slice(0, 4), entry.data.slice(4, 6) - 1, entry.data.slice(6, 8));
const formattedDate = `${date.getDate().toString().padStart(2, '0')}.${(date.getMonth() + 1).toString().padStart(2, '0')}.${date.getFullYear()}`;
const dayShortName = getDayShortName(date);
return `${formattedDate} (${dayShortName})`;
});
const visitorsCounts = entries.map(entry => entry.visitors.count);
// Настройка графика
const ctx = document.getElementById('statsChart').getContext('2d');
const statsChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [
{
type: 'bar',
label: 'Посетители',
data: visitorsCounts,
backgroundColor: 'rgba(75, 192, 192, 0.5)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
},
{
type: 'line',
label: 'Линия посетителей',
data: visitorsCounts,
fill: true, // Включаем заливку
backgroundColor: 'rgba(255, 99, 132, 0.2)', // Цвет заливки
borderColor: 'rgba(255, 99, 132, 1)',
tension: 0.4, // Уровень сглаживания линии
pointRadius: 0 // Убираем точки
}
]
},
options: {
responsive: true,
scales: {
x: {
display: false // Скрыть метки на оси X
},
y: {
beginAtZero: true
}
},
plugins: {
legend: {
display: false // Убираем отображение легенды
},
tooltip: {
callbacks: {
title: (tooltipItems) => {
const index = tooltipItems[0].dataIndex;
return labels[index];
},
label: (tooltipItem) => {
const value = tooltipItem.raw;
return `Посетителей: ${value}`;
}
}
}
}
}
});
})
.catch(error => {
console.error('Ошибка:', error);
});
</script>
Для локального тестирования разместить файл сгенерированный скриптом create-report-wildserver.ru.sh
в каталог static/stat/stat.json
Итог
Наблюдаем симпатишный счетчик посетителей отлично вписавшийся в дизайн сайта. С данными статистики надо будет еще разобрацо, точнее с конфигом GoAccess. Данные разнятся с гугловскими, кто то из них пиждит одназначно, меня конечно радуют большие цифры посещений, которые выдает мой счетчик. Хоть в настройках и сделал так что бы не учитывались заходы пауков, но надо будет еще добавить кастомный лист. В конфиге среди комментариев была ссылочка на дополнительный лист https://raw.githubusercontent.com/allinurl/goaccess/master/config/browsers.list надо изучить поюзать тему. В целом я доволен проделанной работой.
Комментарии