1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using Antmicro.Renode.UserInterface.Tokenizer; 9 using AntShell.Commands; 10 using Antmicro.Renode.Logging; 11 using Antmicro.Renode.Core; 12 using Antmicro.Renode.Peripherals; 13 using System.Linq; 14 using System.Collections.Generic; 15 16 namespace Antmicro.Renode.UserInterface.Commands 17 { 18 public class LogLevelCommand : AutoLoadCommand 19 { PrintHelp(ICommandInteraction writer)20 public override void PrintHelp(ICommandInteraction writer) 21 { 22 base.PrintHelp(writer); 23 writer.WriteLine(); 24 writer.WriteLine("Usages:"); 25 writer.WriteLine(" logLevel"); 26 writer.WriteLine(" logLevel [LEVEL]"); 27 writer.WriteLine(" logLevel [LEVEL] [OBJECT]"); 28 writer.WriteLine(" logLevel [LEVEL] [BACKEND]"); 29 writer.WriteLine(" logLevel [LEVEL] [BACKEND] [OBJECT]"); 30 writer.WriteLine(); 31 writer.WriteLine("To see currently available backends execute command: logLevel"); 32 writer.WriteLine(); 33 PrintAvailableLevels(writer); 34 } 35 36 [Runnable] Run(ICommandInteraction writer)37 public void Run(ICommandInteraction writer) 38 { 39 PrintCurrentLevels(writer); 40 } 41 42 [Runnable] Run([Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level)43 public void Run([Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level) 44 { 45 TrySetLogLevel((LogLevel)level.Value); 46 } 47 48 [Runnable] Run([Values(R, R, R, R, R)] StringToken level)49 public void Run([Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level) 50 { 51 TrySetLogLevel(LogLevel.Parse(level.Value)); 52 } 53 54 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken emulationElementOrBackendName)55 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken emulationElementOrBackendName) 56 { 57 RunInner(writer, (LogLevel)level.Value, emulationElementOrBackendName.Value); 58 } 59 60 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, StringToken emulationElementOrBackendName)61 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, StringToken emulationElementOrBackendName) 62 { 63 RunInner(writer, (LogLevel)level.Value, emulationElementOrBackendName.Value); 64 } 65 66 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken emulationElementOrBackendName, BooleanToken recursive)67 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken emulationElementOrBackendName, BooleanToken recursive) 68 { 69 RunInner(writer, (LogLevel)level.Value, emulationElementOrBackendName.Value, recursive.Value); 70 } 71 72 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, StringToken emulationElementOrBackendName, BooleanToken recursive)73 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, StringToken emulationElementOrBackendName, BooleanToken recursive) 74 { 75 RunInner(writer, (LogLevel)level.Value, emulationElementOrBackendName.Value, recursive.Value); 76 } 77 78 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, LiteralToken emulationElementOrBackendName)79 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, LiteralToken emulationElementOrBackendName) 80 { 81 RunInner(writer, LogLevel.Parse(level.Value), emulationElementOrBackendName.Value); 82 } 83 84 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, StringToken emulationElementOrBackendName)85 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, StringToken emulationElementOrBackendName) 86 { 87 RunInner(writer, LogLevel.Parse(level.Value), emulationElementOrBackendName.Value); 88 } 89 90 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, LiteralToken emulationElementOrBackendName, BooleanToken recursive)91 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, LiteralToken emulationElementOrBackendName, BooleanToken recursive) 92 { 93 RunInner(writer, LogLevel.Parse(level.Value), emulationElementOrBackendName.Value, recursive.Value); 94 } 95 96 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, StringToken emulationElementOrBackendName, BooleanToken recursive)97 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, StringToken emulationElementOrBackendName, BooleanToken recursive) 98 { 99 RunInner(writer, LogLevel.Parse(level.Value), emulationElementOrBackendName.Value, recursive.Value); 100 } 101 102 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, LiteralToken emulationElementName)103 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, LiteralToken emulationElementName) 104 { 105 RunInner(writer, (LogLevel)level.Value, backendName.Value, emulationElementName.Value); 106 } 107 108 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, StringToken emulationElementName)109 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, StringToken emulationElementName) 110 { 111 RunInner(writer, (LogLevel)level.Value, backendName.Value, emulationElementName.Value); 112 } 113 114 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, LiteralToken emulationElementName, BooleanToken recursive)115 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, LiteralToken emulationElementName, BooleanToken recursive) 116 { 117 RunInner(writer, (LogLevel)level.Value, backendName.Value, emulationElementName.Value, recursive.Value); 118 } 119 120 [Runnable] Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, StringToken emulationElementName, BooleanToken recursive)121 public void Run(ICommandInteraction writer, [Values(-1L, 0L, 1L, 2L, 3L)] DecimalIntegerToken level, LiteralToken backendName, StringToken emulationElementName, BooleanToken recursive) 122 { 123 RunInner(writer, (LogLevel)level.Value, backendName.Value, emulationElementName.Value, recursive.Value); 124 } 125 126 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, LiteralToken backendName, LiteralToken emulationElementName)127 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, LiteralToken backendName, LiteralToken emulationElementName) 128 { 129 RunInner(writer, LogLevel.Parse(level.Value), backendName.Value, emulationElementName.Value); 130 } 131 132 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, LiteralToken backendName, StringToken emulationElementName)133 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, LiteralToken backendName, StringToken emulationElementName) 134 { 135 RunInner(writer, LogLevel.Parse(level.Value), backendName.Value, emulationElementName.Value); 136 } 137 138 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, LiteralToken backendName, LiteralToken emulationElementName, BooleanToken recursive)139 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, LiteralToken backendName, LiteralToken emulationElementName, BooleanToken recursive) 140 { 141 RunInner(writer, LogLevel.Parse(level.Value), backendName.Value, emulationElementName.Value, recursive.Value); 142 } 143 144 [Runnable] Run(ICommandInteraction writer, [Values(R, R, R, R, R)] StringToken level, LiteralToken backendName, StringToken emulationElementName, BooleanToken recursive)145 public void Run(ICommandInteraction writer, [Values("Noisy", "Debug", "Info", "Warning", "Error")] StringToken level, LiteralToken backendName, StringToken emulationElementName, BooleanToken recursive) 146 { 147 RunInner(writer, LogLevel.Parse(level.Value), backendName.Value, emulationElementName.Value, recursive.Value); 148 } 149 RunInner(ICommandInteraction writer, LogLevel level, string emulationElementOrBackendName, bool recursive = true)150 private void RunInner(ICommandInteraction writer, LogLevel level, string emulationElementOrBackendName, bool recursive = true) 151 { 152 if(!TrySetLogLevel(level, null, emulationElementOrBackendName, recursive) 153 && !TrySetLogLevel(level, emulationElementOrBackendName, null)) 154 { 155 writer.WriteError(string.Format("Could not find emulation element or backend named: {0}", emulationElementOrBackendName)); 156 } 157 } 158 RunInner(ICommandInteraction writer, LogLevel level, string backendName, string emulationElementName, bool recursive = true)159 private void RunInner(ICommandInteraction writer, LogLevel level, string backendName, string emulationElementName, bool recursive = true) 160 { 161 if(!TrySetLogLevel(level, backendName, emulationElementName, recursive)) 162 { 163 writer.WriteError(string.Format("Could not find emulation element or backend")); 164 } 165 } 166 TrySetLogLevel(LogLevel level, string backendName = null, string emulationElementName = null, bool recursive = true)167 private bool TrySetLogLevel(LogLevel level, string backendName = null, string emulationElementName = null, bool recursive = true) 168 { 169 IEnumerable<IEmulationElement> emulationElements = null; 170 var emulation = EmulationManager.Instance.CurrentEmulation; 171 172 if(emulationElementName != null) 173 { 174 if(!emulation.TryGetEmulationElementByName(emulationElementName, monitor.Machine, out var emulationElement)) 175 { 176 return false; 177 } 178 179 emulationElements = ((emulationElement is IMachine) && recursive) 180 ? (emulationElement as Machine).GetRegisteredPeripherals().Select(x => x.Peripheral).Cast<IEmulationElement>() 181 : new[] { emulationElement }; 182 } 183 184 var emulationElementsIds = (emulationElements == null) 185 ? new[] { -1 } 186 : emulationElements.Select(x => emulation.CurrentLogger.GetOrCreateSourceId(x)).ToArray(); 187 188 bool somethingWasSet = false; 189 foreach(var b in Logger.GetBackends() 190 .Where(x => x.Value.IsControllable) 191 .Where(x => (backendName == null || x.Key == backendName))) 192 { 193 foreach(var emulationElementId in emulationElementsIds) 194 { 195 b.Value.SetLogLevel(level, emulationElementId); 196 somethingWasSet = true; 197 } 198 } 199 200 return somethingWasSet; 201 } 202 PrintAvailableLevels(ICommandInteraction writer)203 private void PrintAvailableLevels(ICommandInteraction writer) 204 { 205 writer.WriteLine("Available levels:\n"); 206 writer.WriteLine(string.Format("{0,-18}| {1}", "Level", "Name")); 207 writer.WriteLine("======================================="); 208 foreach(var item in LogLevel.AvailableLevels) 209 { 210 writer.WriteLine(string.Format("{0,-18}: {1}", item.NumericLevel, item)); 211 } 212 writer.WriteLine(); 213 } 214 PrintCurrentLevels(ICommandInteraction writer)215 private void PrintCurrentLevels(ICommandInteraction writer) 216 { 217 string objectName; 218 string machineName; 219 220 writer.WriteLine("Currently set levels:\n"); 221 writer.WriteLine(string.Format("{0,-18}| {1,-36}| {2}", "Backend", "Emulation element", "Level")); 222 writer.WriteLine("================================================================="); 223 foreach(var backend in Logger.GetBackends().Where(b => b.Value.IsControllable)) 224 { 225 writer.WriteLine(string.Format("{0,-18}: {1,-36}: {2}", backend.Key, string.Empty, backend.Value.GetLogLevel())); 226 foreach (var custom in backend.Value.GetCustomLogLevels()) 227 { 228 EmulationManager.Instance.CurrentEmulation.CurrentLogger.TryGetName(custom.Key, out objectName, out machineName); 229 writer.WriteLine(string.Format("{0,-18}: {1,-36}: {2}", string.Empty, string.Format("{0}:{1}", machineName, objectName), custom.Value)); 230 } 231 writer.WriteLine("-----------------------------------------------------------------"); 232 } 233 } 234 LogLevelCommand(Monitor monitor)235 public LogLevelCommand(Monitor monitor) : base(monitor, "logLevel", "sets logging level for backends.") 236 { 237 } 238 } 239 } 240 241