Session_End не является надежным.
Я хотел бы предложить, чтобы в Session_Start вы создавали запись, которая отмечала время создания сеанса, а в Session_End вы обновляли запись в момент ее окончания.
Чтобы обработать большинство сеансов, которые пассивно прерваны, используйте Application_BeginRequest, чтобы обновить запись, чтобы отметить, когда пользователь был «последний раз замечен».
Затем вам нужно будет определить способ маркировки сеансов, которые были пассивно прекращены. Это будет зависеть от сайта / приложения. Это может быть так же просто, как выбрать количество минут, которое должно пройти, прежде чем сессия будет считаться прекращенной - например, 10 минут.
Итак, у вас есть запрос:
SELECT Username,
SessionStart,
SessionEnd,
LastSeenOn,
DATEDIFF(mi, SessionStart, ISNULL(SessionEnd, LastSeenOn)) DurationMinutes
FROM SessionAudit
WHERE SessionEnd IS NOT NULL
OR DATEDIFF(mi, LastSeenOn, getdate()) > 10
Что вернет ваш журнал аудита сеанса.