mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
add log
This commit is contained in:
@@ -142,6 +142,8 @@ internal static class LayoutCommands
|
||||
|
||||
public static (int ExitCode, string Output) SetLayout(string[] args, Action<uint> notifyFancyZones, uint wmPrivAppliedLayoutsFileUpdate)
|
||||
{
|
||||
Logger.LogInfo($"SetLayout called with args: [{string.Join(", ", args)}]");
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
return (1, "Error: set-layout requires a UUID parameter");
|
||||
@@ -251,9 +253,11 @@ internal static class LayoutCommands
|
||||
|
||||
// Write back to file
|
||||
FancyZonesData.WriteAppliedLayouts(appliedLayouts);
|
||||
Logger.LogInfo($"Applied layouts file updated for {monitorsToUpdate.Count} monitor(s)");
|
||||
|
||||
// Notify FancyZones to reload
|
||||
notifyFancyZones(wmPrivAppliedLayoutsFileUpdate);
|
||||
Logger.LogInfo("FancyZones notified of layout change");
|
||||
|
||||
string layoutName = targetCustomLayout?.Name ?? targetTemplate?.Type ?? uuid;
|
||||
if (applyToAll)
|
||||
|
||||
@@ -84,9 +84,12 @@ internal static class FancyZonesData
|
||||
result = null;
|
||||
error = null;
|
||||
|
||||
Logger.LogDebug($"Reading file: {filePath}");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
error = $"File not found: {Path.GetFileName(filePath)}";
|
||||
Logger.LogWarning(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -97,19 +100,23 @@ internal static class FancyZonesData
|
||||
if (result == null)
|
||||
{
|
||||
error = $"Failed to parse {Path.GetFileName(filePath)}";
|
||||
Logger.LogError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"Successfully read {Path.GetFileName(filePath)}");
|
||||
return true;
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
error = $"JSON parse error in {Path.GetFileName(filePath)}: {ex.Message}";
|
||||
Logger.LogError(error, ex);
|
||||
return false;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
error = $"Failed to read {Path.GetFileName(filePath)}: {ex.Message}";
|
||||
Logger.LogError(error, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -127,7 +134,9 @@ internal static class FancyZonesData
|
||||
|
||||
private static void WriteJsonFile<T>(string filePath, T data, JsonTypeInfo<T> jsonTypeInfo)
|
||||
{
|
||||
Logger.LogDebug($"Writing file: {filePath}");
|
||||
var json = JsonSerializer.Serialize(data, jsonTypeInfo);
|
||||
File.WriteAllText(filePath, json);
|
||||
Logger.LogInfo($"Successfully wrote {Path.GetFileName(filePath)}");
|
||||
}
|
||||
}
|
||||
|
||||
126
src/modules/fancyzones/FancyZonesCLI/Logger.cs
Normal file
126
src/modules/fancyzones/FancyZonesCLI/Logger.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace FancyZonesCLI;
|
||||
|
||||
/// <summary>
|
||||
/// Simple logger for FancyZones CLI.
|
||||
/// Logs to %LOCALAPPDATA%\Microsoft\PowerToys\FancyZones\CLI\Logs
|
||||
/// </summary>
|
||||
internal static class Logger
|
||||
{
|
||||
private static readonly object LockObj = new();
|
||||
private static string _logFilePath = string.Empty;
|
||||
private static bool _isInitialized;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the current log file.
|
||||
/// </summary>
|
||||
public static string LogFilePath => _logFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the logger.
|
||||
/// </summary>
|
||||
public static void InitializeLogger()
|
||||
{
|
||||
if (_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
var logDirectory = Path.Combine(localAppData, "Microsoft", "PowerToys", "FancyZones", "CLI", "Logs");
|
||||
|
||||
if (!Directory.Exists(logDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(logDirectory);
|
||||
}
|
||||
|
||||
var logFileName = $"FancyZonesCLI_{DateTime.Now:yyyy-MM-dd}.log";
|
||||
_logFilePath = Path.Combine(logDirectory, logFileName);
|
||||
_isInitialized = true;
|
||||
|
||||
LogInfo("FancyZones CLI started");
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Silently fail if logging cannot be initialized
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message.
|
||||
/// </summary>
|
||||
public static void LogError(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
Log("ERROR", message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message with exception details.
|
||||
/// </summary>
|
||||
public static void LogError(string message, Exception ex, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
var fullMessage = ex == null
|
||||
? message
|
||||
: $"{message} | Exception: {ex.GetType().Name}: {ex.Message}";
|
||||
Log("ERROR", fullMessage, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a warning message.
|
||||
/// </summary>
|
||||
public static void LogWarning(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
Log("WARN", message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an informational message.
|
||||
/// </summary>
|
||||
public static void LogInfo(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
Log("INFO", message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a debug message (only in DEBUG builds).
|
||||
/// </summary>
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
public static void LogDebug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
Log("DEBUG", message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
private static void Log(string level, string message, string memberName, string sourceFilePath, int sourceLineNumber)
|
||||
{
|
||||
if (!_isInitialized || string.IsNullOrEmpty(_logFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var fileName = Path.GetFileName(sourceFilePath);
|
||||
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
|
||||
var logEntry = $"[{timestamp}] [{level}] [{fileName}:{sourceLineNumber}] [{memberName}] {message}{Environment.NewLine}";
|
||||
|
||||
lock (LockObj)
|
||||
{
|
||||
File.AppendAllText(_logFilePath, logEntry);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Silently fail if logging fails
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@ internal sealed class Program
|
||||
{
|
||||
private static int Main(string[] args)
|
||||
{
|
||||
// Initialize logger
|
||||
Logger.InitializeLogger();
|
||||
Logger.LogInfo($"CLI invoked with args: [{string.Join(", ", args)}]");
|
||||
|
||||
// Initialize Windows messages
|
||||
NativeMethods.InitializeWindowMessages();
|
||||
|
||||
@@ -48,6 +52,16 @@ internal sealed class Program
|
||||
};
|
||||
}
|
||||
|
||||
// Log result
|
||||
if (result.ExitCode == 0)
|
||||
{
|
||||
Logger.LogInfo($"Command completed successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning($"Command failed with exit code {result.ExitCode}: {result.Output}");
|
||||
}
|
||||
|
||||
// Output result
|
||||
if (!string.IsNullOrEmpty(result.Output))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user