You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Logger.cs 5.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using LLama.Native;
  2. using System;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using static LLama.Common.ILLamaLogger;
  6. namespace LLama.Common;
  7. public interface ILLamaLogger
  8. {
  9. public enum LogLevel
  10. {
  11. Debug = 1,
  12. Error = 2,
  13. Warning = 3,
  14. Info = 4
  15. }
  16. /// <summary>
  17. /// Write the log in customized way
  18. /// </summary>
  19. /// <param name="source">The source of the log. It may be a method name or class name.</param>
  20. /// <param name="message">The message.</param>
  21. /// <param name="level">The log level.</param>
  22. void Log(string source, string message, LogLevel level);
  23. }
  24. /// <summary>
  25. /// The default logger of LLamaSharp. On default it write to console. User methods of `LLamaLogger.Default` to change the behavior.
  26. /// It's more recommended to inherit `ILLamaLogger` to customize the behavior.
  27. /// </summary>
  28. public sealed class LLamaDefaultLogger : ILLamaLogger
  29. {
  30. private static readonly Lazy<LLamaDefaultLogger> _instance = new Lazy<LLamaDefaultLogger>(() => new LLamaDefaultLogger());
  31. private bool _toConsole = true;
  32. private bool _toFile = false;
  33. private FileStream? _fileStream = null;
  34. private StreamWriter _fileWriter = null;
  35. public static LLamaDefaultLogger Default => _instance.Value;
  36. private LLamaDefaultLogger()
  37. {
  38. }
  39. /// <summary>
  40. /// Enable logging output from llama.cpp
  41. /// </summary>
  42. /// <returns></returns>
  43. public LLamaDefaultLogger EnableNative()
  44. {
  45. EnableNativeLogCallback();
  46. return this;
  47. }
  48. public LLamaDefaultLogger EnableConsole()
  49. {
  50. _toConsole = true;
  51. return this;
  52. }
  53. public LLamaDefaultLogger DisableConsole()
  54. {
  55. _toConsole = false;
  56. return this;
  57. }
  58. public LLamaDefaultLogger EnableFile(string filename, FileMode mode = FileMode.Append)
  59. {
  60. _fileStream = new FileStream(filename, mode, FileAccess.Write);
  61. _fileWriter = new StreamWriter(_fileStream);
  62. _toFile = true;
  63. return this;
  64. }
  65. public LLamaDefaultLogger DisableFile(string filename)
  66. {
  67. if (_fileWriter is not null)
  68. {
  69. _fileWriter.Close();
  70. _fileWriter = null;
  71. }
  72. if (_fileStream is not null)
  73. {
  74. _fileStream.Close();
  75. _fileStream = null;
  76. }
  77. _toFile = false;
  78. return this;
  79. }
  80. public void Log(string source, string message, LogLevel level)
  81. {
  82. if (level == LogLevel.Info)
  83. {
  84. Info(message);
  85. }
  86. else if (level == LogLevel.Debug)
  87. {
  88. }
  89. else if (level == LogLevel.Warning)
  90. {
  91. Warn(message);
  92. }
  93. else if (level == LogLevel.Error)
  94. {
  95. Error(message);
  96. }
  97. }
  98. public void Info(string message)
  99. {
  100. message = MessageFormat("info", message);
  101. if (_toConsole)
  102. {
  103. Console.ForegroundColor = ConsoleColor.White;
  104. Console.WriteLine(message);
  105. Console.ResetColor();
  106. }
  107. if (_toFile)
  108. {
  109. Debug.Assert(_fileStream is not null);
  110. Debug.Assert(_fileWriter is not null);
  111. _fileWriter.WriteLine(message);
  112. }
  113. }
  114. public void Warn(string message)
  115. {
  116. message = MessageFormat("warn", message);
  117. if (_toConsole)
  118. {
  119. Console.ForegroundColor = ConsoleColor.Yellow;
  120. Console.WriteLine(message);
  121. Console.ResetColor();
  122. }
  123. if (_toFile)
  124. {
  125. Debug.Assert(_fileStream is not null);
  126. Debug.Assert(_fileWriter is not null);
  127. _fileWriter.WriteLine(message);
  128. }
  129. }
  130. public void Error(string message)
  131. {
  132. message = MessageFormat("error", message);
  133. if (_toConsole)
  134. {
  135. Console.ForegroundColor = ConsoleColor.Red;
  136. Console.WriteLine(message);
  137. Console.ResetColor();
  138. }
  139. if (_toFile)
  140. {
  141. Debug.Assert(_fileStream is not null);
  142. Debug.Assert(_fileWriter is not null);
  143. _fileWriter.WriteLine(message);
  144. }
  145. }
  146. private string MessageFormat(string level, string message)
  147. {
  148. DateTime now = DateTime.Now;
  149. string formattedDate = now.ToString("yyyy.MM.dd HH:mm:ss");
  150. return $"[{formattedDate}][{level}]: {message}";
  151. }
  152. /// <summary>
  153. /// Register native logging callback
  154. /// </summary>
  155. private void EnableNativeLogCallback()
  156. {
  157. // TODO: Move to a more appropriate place once we have a intitialize method
  158. NativeApi.llama_log_set(NativeLogCallback);
  159. }
  160. /// <summary>
  161. /// Callback for native logging function
  162. /// </summary>
  163. /// <param name="level">The log level</param>
  164. /// <param name="message">The log message</param>
  165. private void NativeLogCallback(LogLevel level, string message)
  166. {
  167. if (string.IsNullOrEmpty(message))
  168. return;
  169. // Note that text includes the new line character at the end for most events.
  170. // If your logging mechanism cannot handle that, check if the last character is '\n' and strip it
  171. // if it exists.
  172. // It might not exist for progress report where '.' is output repeatedly.
  173. Log(default!, message.TrimEnd('\n'), level);
  174. }
  175. }