When working with system authentication logs on Linux, administrators often need to extract comprehensive login records including year information. While Solaris provides the fwtmp utility for parsing wtmpx with full timestamp data, Linux's default last command omits the year field in its output.
The standard last command output shows:
$ last
user1 pts/0 192.168.1.100 Tue Nov 7 09:48 still logged in
user2 sshd 10.0.0.15 Mon Nov 6 14:30 - 15:45 (01:15)
Notice the missing year information which complicates historical log analysis.
1. Using last with Custom Formatting
Combine last with awk to reconstruct full timestamps:
last | awk '{
cmd = "date -d\""$4" "$5" "$6"\" +\"%Y-%m-%d %H:%M\""
cmd | getline fulldate
close(cmd)
print $1,$2,$3,fulldate,$7,$8,$9,$10
}'
2. Parsing Binary wtmp Directly
Create a Python script to read /var/log/wtmp:
import struct
from datetime import datetime
WTMP_FORMAT = 'i32s4s32s2s2si4i4i4i4'
WTMP_RECORD = struct.Struct(WTMP_FORMAT)
with open('/var/log/wtmp', 'rb') as f:
while True:
data = f.read(WTMP_RECORD.size)
if not data: break
fields = WTMP_RECORD.unpack(data)
timestamp = fields[7]
print(datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S'))
3. Enhanced Lastlog Implementation
For systems using LDAP, extend lastlog functionality:
#!/bin/bash
getent passwd | cut -d: -f1 | while read user; do
lastlog -u $user | grep -v "Never logged in"
done | awk '{print $1,$5,$6,$7,$8,$9}'
When processing historical logs, always verify the system's timezone settings as timestamps in wtmp are stored in UTC. Use:
timedatectl | grep "Time zone"
And convert timestamps accordingly in your parsing scripts.
For large wtmp files (common in enterprise environments), consider these improvements:
- Use compiled languages (C/Go) for binary parsing
- Implement parallel processing for massive log files
- Cache results when frequently querying the same time ranges
For organizations needing comprehensive audit capabilities:
- Implement SIEM solutions (Splunk, ELK stack)
- Consider commercial products like OSSEC or Wazuh
- Develop custom log forwarders to centralize authentication data
While working with login records, I noticed Linux's last command doesn't display year information by default, unlike Solaris' fwtmp utility which provides complete timestamp data including years. This becomes problematic when analyzing historical login patterns or performing forensic investigations.
Linux stores login records in binary format in:
/var/log/wtmp
/var/log/btmp
/var/run/utmp
These files record user sessions in a compact binary format without human-readable year information in their default output.
1. Using last with Custom Formatting
Try this command to force full timestamp display:
last -F | head -5
This might show complete dates on some systems, but output varies between Linux distributions.
2. Parsing with utmpdump
Most Linux systems include utmpdump which can decode the binary logs:
sudo utmpdump /var/log/wtmp | head -5
Sample output shows complete timestamps:
[7] [03653] [ts/0] [user123] [pts/0 ] [10.0.0.123 ] [10.0.0.123 ] [2023-11-15T09:30:00,000000+00:00]
3. Custom Script Solution
For consistent year output across systems, use this Python script:
#!/usr/bin/env python3
import sys
from datetime import datetime
def parse_last_line(line):
parts = line.split()
if len(parts) < 10:
return line
# Reconstruct timestamp
month_day = ' '.join(parts[-5:-3])
time_year = ' '.join(parts[-3:-1])
timestamp_str = f"{month_day} {time_year}"
try:
dt = datetime.strptime(timestamp_str, '%b %d %H:%M:%S %Y')
return line.replace(timestamp_str, dt.strftime('%Y-%m-%d %H:%M:%S'))
except:
return line
if __name__ == "__main__":
for line in sys.stdin:
print(parse_last_line(line.strip()))
Different Linux distributions handle this differently:
- RHEL/CentOS: May require
utmpdumppackage installation - Debian/Ubuntu:
last -Foften works - Arch Linux: Needs custom compilation of utmp tools
To ensure future logs contain full timestamps, modify your logrotate configuration for wtmp/btmp to preserve complete timestamp information during rotation cycles.