Вопрос или проблема
Я хотел бы получить информацию о “времени использования” пользователей на Linux-системах за определённые дни. Это означает время, когда пользователь имеет разблокированный экран. В отличие от команды ac, которая показывает всё время, когда пользователь вошёл в систему, включая время с заблокированным экраном или в режиме ожидания. Насколько я знаю, время простоя, отображаемое командой who, отличается от времени с разблокированным экраном. Так что это, очевидно, не решение. Программа с открытым исходным кодом Timekpr отображает искомую информацию, но только за текущую неделю. Возможно, можно извлечь код для этого расчёта. Однако мои навыки программирования для этого слишком плохи.
Насколько я знаю, время простоя, отображаемое командой who, отличается от времени с разблокированным экраном.
Нет. who — это программа, которая появилась до графических сессий. Она вообще не имеет представления о том, что такое “заблокированный экран”. В общем, экранный блокировщик — это всего лишь обычная программа, которая запускается во весь экран и перехватывает все ваши нажатия клавиш. Так что, с точки зрения вашего компьютера, пользователь никогда не выходит из системы — он просто не выполняет ничего, пока показывается экран блокировки. В последние годы, к счастью, большинство дистрибутивов Linux пришли к какому-то соглашению о том, как выглядит управление пользовательскими сессиями и местами — так что есть loginctl lock-session (и ваш менеджер сессий может вызвать это внутренне или через dbus для блокировки). Вы могли бы написать программу, которая перехватывает механизм блокировки/разблокировки через dbus и фиксирует время между ними — насколько я знаю, этого пока никто не делает: loginctl session-status имеет представление о возрасте сессии, но не о том, как долго она была назначена месту и разблокирована. В общем, информация, которую вы ищете, кажется весьма сомнительной в использовании — для учётных целей пользователь может выполнять произвольные вычисления/сетевые операции/хранение данных, пока экран заблокирован.
Это не совсем то, что вы спрашиваете, но вы можете найти полезными утилиты учёта GNU (acct).
Утилиты учёта GNU — это набор утилит, который сообщает и обобщает данные о времени подключения пользователей и статистике выполнения процессов. “Учёт входа” предоставляет сводки использования системных ресурсов на основе времени подключения, а “учёт процессов” предоставляет сводки на основе команд, выполняемых в системе.
Эти утилиты должны быть доступны в пакетах для большинства дистрибутивов — например, на Debian и т.д., apt-get install acct. Обратите внимание: отслеживание пользователей и их процессов, времени выполнения и т.д. может повлиять на производительность… вероятно, это будет незначительно на слабо загруженной высокопроизводительной системе, но может быть довольно заметно на сильно загруженной или низкоклассной системе.
Журнал/История временных меток начала/окончания экранной заставки. Смотрите моё решение на https://superuser.com/a/1856536/1794225.
Ответ или решение
Для получения информации о продолжительности активного времени пользователя на системах Linux, когда экран не заблокирован, можно воспользоваться специфическими механизмами отслеживания состояния сессии. Поскольку вы уже заметили, команда who
не учитывает состояние заблокированного экрана, вам потребуется использовать другие подходы.
1. Использование loginctl
В недавних версиях Linux была внедрена система управления сессиями, которая позволяет выполнять команды, используемые для блокировки и разблокировки сессий. Вы можете использовать loginctl
для мониторинга событий блокировки и разблокировки сессий. Однако из коробки loginctl
не предоставляет прямую информацию о времени, когда экран был разблокирован.
2. Создание собственного сценария
Вы можете написать небольшой скрипт на Python или Bash, который будет взаимодействовать с D-Bus для отслеживания событий блокировки и разблокировки. С помощью этой информации можно будет вычислить общее время, когда пользователь находился в активной сессии.
Примерный код на Python может выглядеть следующим образом:
import dbus
import dbus.mainloop.glib
import datetime
from gi.repository import GLib
def session_locked(*args):
global lock_time
lock_time = datetime.datetime.now()
def session_unlocked(*args):
global lock_time, active_time
if lock_time:
unlocked_time = datetime.datetime.now() - lock_time
active_time += unlocked_time.total_seconds()
lock_time = None
print(f"Active time updated: {active_time} seconds")
lock_time = None
active_time = 0
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_signal_receiver(session_locked, dbus_interface='org.freedesktop.login1', signal_name='SessionLock')
bus.add_signal_receiver(session_unlocked, dbus_interface='org.freedesktop.login1', signal_name='SessionUnlock')
# Запуск основного цикла
GLib.MainLoop().run()
Этот скрипт будет отслеживать события блокировки и разблокировки сессии и обновлять общее активное время.
3. Использование утилит учета GNU
Также вы можете рассмотреть возможность использования утилит GNU учета, таких как acct
. Установить их можно с помощью следующей команды на системах Debian и производных:
sudo apt-get install acct
После установки вы можете использовать команды lastcomm
, sa
и другие, чтобы получить отчет о пользователях и их активности. Обратите внимание, что эта утилита отслеживает статистику по выполненным процессам, и может не полностью соответствовать вашему запросу на отслеживание времени активных сессий.
4. Сохранение журналов состояния экрана
Можно также рассмотреть вариант сохранения временных меток начала и окончания сессии в файл журнала. Можно использовать Xorg
для отслеживания событий состояния экрана через .xsession
или .xprofile
:
#!/bin/bash
echo "Session started: $(date)" >> ~/.screen_activity.log
# Команда для блокировки экрана
# После разблокировки:
echo "Session unlocked: $(date)" >> ~/.screen_activity.log
Заключение
Учет времени активной сессии пользователя с исключением времени блокировки экрана в Linux требует реализации дополнительных решений, так как стандартные утилиты не предоставляют такой информации напрямую. Использование D-Bus, создание собственного скрипта для мониторинга состояния сессии и, возможно, интеграция утилит GNU учета может быть целесообразным вариантом.