Add basic general log file

Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
AnErrupTion 2025-08-03 15:59:47 +02:00
parent 3f891d7f0d
commit c3d180c213
No known key found for this signature in database
24 changed files with 96 additions and 16 deletions

View File

@ -58,8 +58,8 @@ body:
attributes:
label: Relevant logs
description: |
Please copy and paste any relevant logs, error messages or any other output. This will be automatically formatted into code, so no need for backticks. Screenshots are accepted if they make life easier for you.
If it exists, ncluding your session log (found at /var/log/ly-session.log unless modified) is a good idea. (But make sure it's relevant!)
Please copy and paste (or attach) any relevant logs, error messages or any other output. This will be automatically formatted into code, so no need for backticks. Screenshots are accepted if they make life easier for you.
Moreover, it is almost always a good idea to include your session log and your general log files (found at ~/ly-session.log and /var/log/ly.log respectively by default) as it usually contains relevant information about the problem.
render: shell
- type: textarea
id: moreinfo

View File

@ -199,6 +199,9 @@ login_defs_path = /etc/login.defs
# no need to add `exec "$@"` at the end
logout_cmd = null
# General log file path
ly_log = /var/log/ly.log
# Main box horizontal margin
margin_box_h = 2

View File

@ -15,6 +15,7 @@ err_empty_password = لا يُسمح بكلمة مرور فارغة
err_envlist = فشل في جلب قائمة المتغيرات البيئية
err_hostname = فشل في جلب اسم المضيف (Hostname)
err_mlock = فشل في تأمين ذاكرة كلمة المرور (mlock)
err_null = مؤشر فارغ (Null pointer)
err_numlock = فشل في ضبط Num Lock

View File

@ -15,6 +15,7 @@ err_domain = domini invàlid
err_envlist = error en obtenir l'envlist
err_hostname = error en obtenir el nom de l'amfitrió
err_mlock = error en bloquejar la memòria de clau
err_null = punter nul
err_numlock = error en establir el Bloq num

View File

@ -15,6 +15,7 @@ err_domain = neplatná doména
err_hostname = nelze získat název hostitele
err_mlock = uzamčení paměti hesel selhalo
err_null = nulový ukazatel

View File

@ -15,6 +15,7 @@ err_empty_password = Leeres Passwort nicht zugelassen
err_envlist = Fehler beim Abrufen der Umgebungs-Variablen
err_hostname = Abrufen des Hostnames fehlgeschlagen
err_mlock = Sperren des Passwortspeichers fehlgeschlagen
err_null = Null Pointer
err_numlock = Numlock konnte nicht aktiviert werden

View File

@ -15,6 +15,7 @@ err_empty_password = empty password not allowed
err_envlist = failed to get envlist
err_hostname = failed to get hostname
err_lock_state = failed to get lock state
err_log = failed to open log file
err_mlock = failed to lock password memory
err_null = null pointer
err_numlock = failed to set numlock

View File

@ -15,6 +15,7 @@ err_domain = dominio inválido
err_hostname = error al obtener el nombre de host
err_mlock = error al bloquear la contraseña de memoria
err_null = puntero nulo

View File

@ -15,6 +15,7 @@ err_empty_password = mot de passe vide non autorisé
err_envlist = échec de lecture de la liste d'environnement
err_hostname = échec de lecture du nom d'hôte
err_lock_state = échec de lecture de l'état de verrouillage
err_log = échec de l'ouverture du fichier de journal
err_mlock = échec du verrouillage mémoire
err_null = pointeur null
err_numlock = échec de modification du verr.num

View File

@ -15,6 +15,7 @@ err_domain = dominio non valido
err_hostname = impossibile ottenere hostname
err_mlock = impossibile ottenere lock per la password in memoria
err_null = puntatore nullo

View File

@ -15,6 +15,7 @@ err_empty_password = 空のパスワードは許可されていません
err_envlist = 環境変数リストの取得に失敗しました
err_hostname = ホスト名の取得に失敗しました
err_mlock = パスワードメモリのロックに失敗しました
err_null = ヌルポインタ
err_numlock = NumLockの設定に失敗しました

View File

@ -15,6 +15,7 @@ err_empty_password = puste hasło jest niedozwolone
err_envlist = nie udało się pobrać listy zmiennych środowiskowych
err_hostname = nie udało się uzyskać nazwy hosta
err_mlock = nie udało się zablokować pamięci haseł
err_null = pusty wskaźnik
err_numlock = nie udało się ustawić numlock

View File

@ -15,6 +15,7 @@ err_domain = domínio inválido
err_hostname = erro ao obter o nome do host
err_mlock = erro de bloqueio de memória
err_null = ponteiro nulo

View File

@ -15,6 +15,7 @@ err_domain = domínio inválido
err_hostname = não foi possível obter o nome do host
err_mlock = bloqueio da memória de senha malsucedido
err_null = ponteiro nulo

View File

@ -19,6 +19,7 @@ capslock = capslock
err_pam_abort = tranzacţie pam anulată
err_pam_acct_expired = cont expirat
err_pam_auth = eroare de autentificare

View File

@ -15,6 +15,7 @@ err_empty_password = пустой пароль не допустим
err_envlist = не удалось получить список переменных среды
err_hostname = не удалось получить имя хоста
err_mlock = сбой блокировки памяти
err_null = нулевой указатель

View File

@ -15,6 +15,7 @@ err_domain = nevazeci domen
err_hostname = neuspijesno trazenje hostname-a
err_mlock = neuspijesno zakljucavanje memorije lozinke
err_null = null pokazivac

View File

@ -15,6 +15,7 @@ err_domain = okänd domän
err_hostname = misslyckades att hämta värdnamn
err_mlock = misslyckades att låsa lösenordsminne
err_null = nullpekare

View File

@ -15,6 +15,7 @@ err_domain = gecersiz etki alani
err_hostname = ana bilgisayar adi alinamadi
err_mlock = parola bellegi kilitlenemedi
err_null = bos isaretci hatasi

View File

@ -15,6 +15,7 @@ err_domain = недійсний домен
err_hostname = не вдалося отримати ім'я хосту
err_mlock = збій блокування пам'яті
err_null = нульовий вказівник

View File

@ -15,6 +15,7 @@ err_domain = 无效的域
err_hostname = 获取主机名失败
err_mlock = 锁定密码存储器失败
err_null = 空指针

View File

@ -54,6 +54,7 @@ load: bool = true,
login_cmd: ?[]const u8 = null,
login_defs_path: []const u8 = "/etc/login.defs",
logout_cmd: ?[]const u8 = null,
ly_log: []const u8 = "/var/log/ly.log",
margin_box_h: u8 = 2,
margin_box_v: u8 = 1,
min_refresh_delta: u16 = 5,

View File

@ -20,6 +20,7 @@ err_empty_password: []const u8 = "empty password not allowed",
err_envlist: []const u8 = "failed to get envlist",
err_hostname: []const u8 = "failed to get hostname",
err_lock_state: []const u8 = "failed to get lock state",
err_log: []const u8 = "failed to open log file",
err_mlock: []const u8 = "failed to lock password memory",
err_null: []const u8 = "null pointer",
err_numlock: []const u8 = "failed to set numlock",

View File

@ -201,6 +201,25 @@ pub fn main() !void {
migrator.lateConfigFieldHandler(&config.animation);
}
var log_file: std.fs.File = undefined;
defer log_file.close();
var could_open_log_file = true;
open_log_file: {
log_file = std.fs.cwd().openFile(config.ly_log, .{ .mode = .write_only }) catch std.fs.cwd().createFile(config.ly_log, .{ .mode = 0o666 }) catch {
// If we could neither open an existing log file nor create a new
// one, abort.
could_open_log_file = false;
break :open_log_file;
};
}
if (!could_open_log_file) {
log_file = try std.fs.openFileAbsolute("/dev/null", .{ .mode = .write_only });
}
const log_writer = log_file.writer();
// if (migrator.mapped_config_fields) save_migrated_config: {
// var file = try std.fs.cwd().createFile(config_path, .{});
// defer file.close();
@ -217,8 +236,12 @@ pub fn main() !void {
restart_cmd = try temporary_allocator.dupe(u8, config.restart_cmd);
// Initialize termbox
try log_writer.writeAll("initializing termbox2\n");
_ = termbox.tb_init();
defer _ = termbox.tb_shutdown();
defer {
log_writer.writeAll("shutting down termbox2\n") catch {};
_ = termbox.tb_shutdown();
}
const act = std.posix.Sigaction{
.handler = .{ .handler = &signalHandler },
@ -255,6 +278,8 @@ pub fn main() !void {
};
var buffer = TerminalBuffer.init(buffer_options, labels_max_length, random);
try log_writer.print("screen resolution is {d}x{d}\n", .{ buffer.width, buffer.height });
// Initialize components
var info_line = InfoLine.init(allocator, &buffer);
defer info_line.deinit();
@ -262,27 +287,37 @@ pub fn main() !void {
if (config_load_failed) {
// We can't localize this since the config failed to load so we'd fallback to the default language anyway
try info_line.addMessage("unable to parse config file", config.error_bg, config.error_fg);
try log_writer.writeAll("unable to parse config file\n");
}
interop.setNumlock(config.numlock) catch {
if (!could_open_log_file) {
try info_line.addMessage(lang.err_log, config.error_bg, config.error_fg);
try log_writer.writeAll("failed to open log file\n");
}
interop.setNumlock(config.numlock) catch |err| {
try info_line.addMessage(lang.err_numlock, config.error_bg, config.error_fg);
try log_writer.print("failed to set numlock: {s}\n", .{@errorName(err)});
};
var session = Session.init(allocator, &buffer);
defer session.deinit();
addOtherEnvironment(&session, lang, .shell, null) catch {
addOtherEnvironment(&session, lang, .shell, null) catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to add shell environment: {s}\n", .{@errorName(err)});
};
if (build_options.enable_x11_support) {
if (config.xinitrc) |xinitrc_cmd| {
addOtherEnvironment(&session, lang, .xinitrc, xinitrc_cmd) catch {
addOtherEnvironment(&session, lang, .xinitrc, xinitrc_cmd) catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to add xinitrc environment: {s}\n", .{@errorName(err)});
};
}
} else {
try info_line.addMessage(lang.no_x11_support, config.bg, config.fg);
try log_writer.writeAll("x11 support disabled at compile-time\n");
}
if (config.initial_info_text) |text| {
@ -290,8 +325,9 @@ pub fn main() !void {
} else get_host_name: {
// Initialize information line with host name
var name_buf: [std.posix.HOST_NAME_MAX]u8 = undefined;
const hostname = std.posix.gethostname(&name_buf) catch {
const hostname = std.posix.gethostname(&name_buf) catch |err| {
try info_line.addMessage(lang.err_hostname, config.error_bg, config.error_fg);
try log_writer.print("failed to get hostname: {s}\n", .{@errorName(err)});
break :get_host_name;
};
try info_line.addMessage(hostname, config.bg, config.fg);
@ -327,6 +363,7 @@ pub fn main() !void {
// accounts *and* no root account...but at this point, if that's the
// case, you have bigger problems to deal with in the first place. :D
try info_line.addMessage(lang.err_no_users, config.error_bg, config.error_fg);
try log_writer.writeAll("no users found\n");
}
var login = try UserList.init(allocator, &buffer, usernames);
@ -374,8 +411,9 @@ pub fn main() !void {
.info_line => info_line.label.handle(null, insert_mode),
.session => session.label.handle(null, insert_mode),
.login => login.label.handle(null, insert_mode),
.password => password.handle(null, insert_mode) catch {
.password => password.handle(null, insert_mode) catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to handle password input: {s}\n", .{@errorName(err)});
},
}
}
@ -426,8 +464,9 @@ pub fn main() !void {
var auth_fails: u64 = 0;
// Switch to selected TTY
interop.switchTty(config.tty) catch {
interop.switchTty(config.tty) catch |err| {
try info_line.addMessage(lang.err_switch_tty, config.error_bg, config.error_fg);
try log_writer.print("failed to switch tty: {s}\n", .{@errorName(err)});
};
while (run) {
@ -442,12 +481,14 @@ pub fn main() !void {
if (width != buffer.width or height != buffer.height) {
// If it did change, then update the cell buffer, reallocate the current animation's buffers, and force a draw update
try log_writer.print("screen resolution updated to {d}x{d}\n", .{ width, height });
buffer.width = width;
buffer.height = height;
animation.realloc() catch {
animation.realloc() catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to reallocate animation buffers: {s}\n", .{@errorName(err)});
};
update = true;
@ -518,8 +559,9 @@ pub fn main() !void {
.info_line => info_line.label.handle(null, insert_mode),
.session => session.label.handle(null, insert_mode),
.login => login.label.handle(null, insert_mode),
.password => password.handle(null, insert_mode) catch {
.password => password.handle(null, insert_mode) catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to handle password input: {s}\n", .{@errorName(err)});
},
}
@ -532,6 +574,7 @@ pub fn main() !void {
if (clock_str.len == 0) {
try info_line.addMessage(lang.err_clock_too_long, config.error_bg, config.error_fg);
can_draw_clock = false;
try log_writer.writeAll("clock string too long\n");
break :draw_clock;
}
@ -599,9 +642,10 @@ pub fn main() !void {
}
if (can_get_lock_state) draw_lock_state: {
const lock_state = interop.getLockState() catch {
const lock_state = interop.getLockState() catch |err| {
try info_line.addMessage(lang.err_lock_state, config.error_bg, config.error_fg);
can_get_lock_state = false;
try log_writer.print("failed to get lock state: {s}\n", .{@errorName(err)});
break :draw_lock_state;
};
@ -682,16 +726,19 @@ pub fn main() !void {
};
if (process_result.Exited != 0) {
try info_line.addMessage(lang.err_sleep, config.error_bg, config.error_fg);
try log_writer.print("failed to execute sleep command: exit code {d}\n", .{process_result.Exited});
}
}
}
} else if (brightness_down_key != null and pressed_key == brightness_down_key.?) {
adjustBrightness(allocator, config.brightness_down_cmd) catch {
adjustBrightness(allocator, config.brightness_down_cmd) catch |err| {
try info_line.addMessage(lang.err_brightness_change, config.error_bg, config.error_fg);
try log_writer.print("failed to change brightness: {s}\n", .{@errorName(err)});
};
} else if (brightness_up_key != null and pressed_key == brightness_up_key.?) {
adjustBrightness(allocator, config.brightness_up_cmd) catch {
adjustBrightness(allocator, config.brightness_up_cmd) catch |err| {
try info_line.addMessage(lang.err_brightness_change, config.error_bg, config.error_fg);
try log_writer.print("failed to change brightness: {s}\n", .{@errorName(err)});
};
}
},
@ -735,10 +782,14 @@ pub fn main() !void {
update = true;
},
termbox.TB_KEY_ENTER => authenticate: {
try log_writer.writeAll("authenticating...");
if (!config.allow_empty_password and password.text.items.len == 0) {
// Let's not log this message for security reasons
try info_line.addMessage(lang.err_empty_password, config.error_bg, config.error_fg);
InfoLine.clearRendered(allocator, buffer) catch {
InfoLine.clearRendered(allocator, buffer) catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to clear info line: {s}\n", .{@errorName(err)});
};
info_line.label.draw();
_ = termbox.tb_present();
@ -746,8 +797,9 @@ pub fn main() !void {
}
try info_line.addMessage(lang.authenticating, config.bg, config.fg);
InfoLine.clearRendered(allocator, buffer) catch {
InfoLine.clearRendered(allocator, buffer) catch |err| {
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
try log_writer.print("failed to clear info line: {s}\n", .{@errorName(err)});
};
info_line.label.draw();
_ = termbox.tb_present();
@ -820,7 +872,10 @@ pub fn main() !void {
if (auth_err) |err| {
auth_fails += 1;
active_input = .password;
try info_line.addMessage(getAuthErrorMsg(err, lang), config.error_bg, config.error_fg);
try log_writer.print("failed to authenticate: {s}\n", .{@errorName(err)});
if (config.clear_password or err != error.PamAuthError) password.clear();
} else {
if (config.logout_cmd) |logout_cmd| {
@ -830,6 +885,7 @@ pub fn main() !void {
password.clear();
try info_line.addMessage(lang.logout, config.bg, config.fg);
try log_writer.writeAll("logged out");
}
try std.posix.tcsetattr(std.posix.STDIN_FILENO, .FLUSH, tb_termios);