diff --git a/dotnet/src/webdriver/Internal/Logging/ConsoleLogHandler.cs b/dotnet/src/webdriver/Internal/Logging/ConsoleLogHandler.cs index cc71fb390b706..3e51d5e3dbc82 100644 --- a/dotnet/src/webdriver/Internal/Logging/ConsoleLogHandler.cs +++ b/dotnet/src/webdriver/Internal/Logging/ConsoleLogHandler.cs @@ -1,8 +1,29 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + using System; using System.Collections.Generic; namespace OpenQA.Selenium.Internal.Logging { + /// + /// Represents a log handler that writes log events to the console. + /// public class ConsoleLogHandler : ILogHandler { private static readonly Dictionary _levelMap = new Dictionary @@ -14,11 +35,19 @@ public class ConsoleLogHandler : ILogHandler { LogEventLevel.Error, "ERR" } }; + /// + /// Handles a log event by writing it to the console. + /// + /// The log event to handle. public void Handle(LogEvent logEvent) { Console.WriteLine($"{logEvent.Timestamp:HH:mm:ss.fff} {_levelMap[logEvent.Level]} {logEvent.IssuedBy.Name}: {logEvent.Message}"); } + /// + /// Creates a new instance of the class. + /// + /// A new instance of the class. public ILogHandler Clone() { return this; diff --git a/dotnet/src/webdriver/Internal/Logging/ILogContext.cs b/dotnet/src/webdriver/Internal/Logging/ILogContext.cs index e672c151b13e6..55042ebffcf12 100644 --- a/dotnet/src/webdriver/Internal/Logging/ILogContext.cs +++ b/dotnet/src/webdriver/Internal/Logging/ILogContext.cs @@ -1,23 +1,85 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + using System; namespace OpenQA.Selenium.Internal.Logging { + /// + /// Represents a logging context that provides methods for creating sub-contexts, retrieving loggers, emitting log messages, and configuring minimum log levels. + /// public interface ILogContext : IDisposable { + /// + /// Creates a new logging context. + /// + /// A new instance of . ILogContext CreateContext(); + /// + /// Creates a new logging context with the specified minimum log level. + /// + /// The minimum log level for the new context. + /// A new instance of with the specified minimum log level. ILogContext CreateContext(LogEventLevel minimumLevel); + /// + /// Gets a logger for the specified type. + /// + /// The type for which to retrieve the logger. + /// An instance of for the specified type. ILogger GetLogger(); + /// + /// Gets a logger for the specified type. + /// + /// The type for which to retrieve the logger. + /// An instance of for the specified type. ILogger GetLogger(Type type); + /// + /// Emits a log message using the specified logger, log level, and message. + /// + /// The logger to emit the log message. + /// The log level of the message. + /// The log message. void EmitMessage(ILogger logger, LogEventLevel level, string message); + /// + /// Sets the minimum log level for the current context. + /// + /// The minimum log level. + /// The current instance of with the minimum log level set. ILogContext SetMinimumLevel(LogEventLevel level); + /// + /// Sets the minimum log level for the specified type in the current context. + /// + /// The type for which to set the minimum log level. + /// The minimum log level. + /// The current instance of with the minimum log level set for the specified type. ILogContext SetMinimumLevel(Type issuer, LogEventLevel level); + /// + /// Adds a log handler to the current context. + /// + /// The log handler to add. + /// The current instance of with the log handler added. ILogContext WithHandler(ILogHandler handler); } } diff --git a/dotnet/src/webdriver/Internal/Logging/ILogHandler.cs b/dotnet/src/webdriver/Internal/Logging/ILogHandler.cs index 25a2307bf1bba..44c3ae67f6377 100644 --- a/dotnet/src/webdriver/Internal/Logging/ILogHandler.cs +++ b/dotnet/src/webdriver/Internal/Logging/ILogHandler.cs @@ -1,11 +1,38 @@ -using System; +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// namespace OpenQA.Selenium.Internal.Logging { + /// + /// Represents a log handler that handles log events. + /// public interface ILogHandler { + /// + /// Handles a log event. + /// + /// The log event to handle. void Handle(LogEvent logEvent); + /// + /// Creates a clone of the log handler. + /// + /// A clone of the log handler. ILogHandler Clone(); } } diff --git a/dotnet/src/webdriver/Internal/Logging/Log.cs b/dotnet/src/webdriver/Internal/Logging/Log.cs index 0a31c5fd9cdda..82f68bb199f3a 100644 --- a/dotnet/src/webdriver/Internal/Logging/Log.cs +++ b/dotnet/src/webdriver/Internal/Logging/Log.cs @@ -1,29 +1,77 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + using System; namespace OpenQA.Selenium.Internal.Logging { + /// + /// Provides context aware logging functionality for the Selenium WebDriver. + /// + /// + /// + /// Use the following code to enable logging to console: + /// + /// Log.SetMinimumLevel(LogEventLevel.Debug)).WithHandler(new ConsoleLogHandler()); + /// + /// + /// Or enable it per limited execution scope: + /// + /// using (var ctx = Log.CreateContext(LogEventLevel.Trace)) + /// { + /// // do something + /// } + /// + /// public static class Log { private static readonly LogContextManager _logContextManager = new LogContextManager(); + /// + /// Creates a new log context with the current context properties and the specified minimum log event level. + /// + /// The created log context. public static ILogContext CreateContext() { - var context = CurrentContext.CreateContext(); + var context = _logContextManager.CurrentContext.CreateContext(); - CurrentContext = context; + _logContextManager.CurrentContext = context; return context; } + /// + /// Creates a new log context with with the current context properties and the specified minimum log event level. + /// + /// The minimum log event level. + /// The created log context. public static ILogContext CreateContext(LogEventLevel minimumLevel) { - var context = CurrentContext.CreateContext(minimumLevel); + var context = _logContextManager.CurrentContext.CreateContext(minimumLevel); - CurrentContext = context; + _logContextManager.CurrentContext = context; return context; } + /// + /// Gets or sets the current log context. + /// internal static ILogContext CurrentContext { get @@ -36,29 +84,55 @@ internal static ILogContext CurrentContext } } + /// + /// Gets a logger for the specified type. + /// + /// The type to get the logger for. + /// The logger. internal static ILogger GetLogger() { - return CurrentContext.GetLogger(); + return _logContextManager.CurrentContext.GetLogger(); } + /// + /// Gets a logger for the specified type. + /// + /// The type to get the logger for. + /// The logger. internal static ILogger GetLogger(Type type) { - return CurrentContext.GetLogger(type); + return _logContextManager.CurrentContext.GetLogger(type); } + /// + /// Sets the minimum log event level for the current log context. + /// + /// The minimum log event level. + /// The current log context. public static ILogContext SetMinimumLevel(LogEventLevel level) { - return CurrentContext.SetMinimumLevel(level); + return _logContextManager.CurrentContext.SetMinimumLevel(level); } + /// + /// Sets the minimum log event level for the specified issuer in the current log context. + /// + /// The issuer type. + /// The minimum log event level. + /// The current log context. public static ILogContext SetMinimumLevel(Type issuer, LogEventLevel level) { - return CurrentContext.SetMinimumLevel(issuer, level); + return _logContextManager.CurrentContext.SetMinimumLevel(issuer, level); } + /// + /// Adds a log handler to the current log context. + /// + /// The log handler to add. + /// The current log context. public static ILogContext WithHandler(ILogHandler handler) { - return CurrentContext.WithHandler(handler); + return _logContextManager.CurrentContext.WithHandler(handler); } } } diff --git a/dotnet/src/webdriver/Internal/Logging/LogContext.cs b/dotnet/src/webdriver/Internal/Logging/LogContext.cs index 5c0b875121b3a..d6750a2a93191 100644 --- a/dotnet/src/webdriver/Internal/Logging/LogContext.cs +++ b/dotnet/src/webdriver/Internal/Logging/LogContext.cs @@ -1,3 +1,21 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -5,11 +23,15 @@ namespace OpenQA.Selenium.Internal.Logging { + /// + /// Represents a logging context that provides methods for creating sub-contexts, retrieving loggers, emitting log messages, and configuring minimum log levels. + /// + /// internal class LogContext : ILogContext { private ConcurrentDictionary _loggers; - private IList _handlers; + private readonly IList _handlers; private LogEventLevel _level; diff --git a/dotnet/src/webdriver/Internal/Logging/LogEvent.cs b/dotnet/src/webdriver/Internal/Logging/LogEvent.cs index fc76fc436bcc1..103194070ee81 100644 --- a/dotnet/src/webdriver/Internal/Logging/LogEvent.cs +++ b/dotnet/src/webdriver/Internal/Logging/LogEvent.cs @@ -1,9 +1,37 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + using System; namespace OpenQA.Selenium.Internal.Logging { + /// + /// Represents a log event in the Selenium WebDriver internal logging system. + /// public sealed class LogEvent { + /// + /// Initializes a new instance of the class. + /// + /// The type that issued the log event. + /// The timestamp of the log event. + /// The level of the log event. + /// The message of the log event. public LogEvent(Type issuedBy, DateTimeOffset timestamp, LogEventLevel level, string message) { IssuedBy = issuedBy; @@ -12,13 +40,24 @@ public LogEvent(Type issuedBy, DateTimeOffset timestamp, LogEventLevel level, st Message = message; } + /// + /// Gets the type that issued the log event. + /// public Type IssuedBy { get; } + /// + /// Gets the timestamp of the log event. + /// public DateTimeOffset Timestamp { get; } + /// + /// Gets the level of the log event. + /// public LogEventLevel Level { get; } + /// + /// Gets the message of the log event. + /// public string Message { get; } - } } diff --git a/dotnet/src/webdriver/Internal/Logging/Logger.cs b/dotnet/src/webdriver/Internal/Logging/Logger.cs index 3ecff0c102be9..9bb2cece9ee6c 100644 --- a/dotnet/src/webdriver/Internal/Logging/Logger.cs +++ b/dotnet/src/webdriver/Internal/Logging/Logger.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.Internal.Logging /// /// The implementation of the interface through which log messages are emitted. /// - /// + /// internal class Logger : ILogger { public Logger(Type issuer, LogEventLevel level)