From 0526161385677fdd8a27dd21611c3e9721d9fc90 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 24 Jul 2015 00:28:16 -0700 Subject: introduce gRPC logger --- src/csharp/Grpc.Core/Grpc.Core.csproj | 7 +- src/csharp/Grpc.Core/GrpcEnvironment.cs | 33 ++++++- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 5 +- src/csharp/Grpc.Core/Internal/AsyncCallBase.cs | 13 ++- .../Grpc.Core/Internal/CompletionRegistry.cs | 5 +- src/csharp/Grpc.Core/Internal/GrpcLog.cs | 94 ------------------ src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs | 10 +- .../Grpc.Core/Internal/NativeLogRedirector.cs | 107 +++++++++++++++++++++ src/csharp/Grpc.Core/Internal/ServerCallHandler.cs | 17 +++- src/csharp/Grpc.Core/Logging/ConsoleLogger.cs | 103 ++++++++++++++++++++ src/csharp/Grpc.Core/Logging/ILogger.cs | 57 +++++++++++ src/csharp/Grpc.Core/Server.cs | 5 +- src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs | 10 +- .../Grpc.IntegrationTesting/SslCredentialsTest.cs | 3 +- 14 files changed, 347 insertions(+), 122 deletions(-) delete mode 100644 src/csharp/Grpc.Core/Internal/GrpcLog.cs create mode 100644 src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs create mode 100644 src/csharp/Grpc.Core/Logging/ConsoleLogger.cs create mode 100644 src/csharp/Grpc.Core/Logging/ILogger.cs (limited to 'src') diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 2705c95a26..0d879e9b1e 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -47,7 +47,6 @@ - @@ -105,6 +104,9 @@ + + + @@ -135,4 +137,7 @@ + + + \ No newline at end of file diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index 47d1651aab..034a66be3c 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -35,6 +35,7 @@ using System; using System.Runtime.InteropServices; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core @@ -55,6 +56,8 @@ namespace Grpc.Core static object staticLock = new object(); static GrpcEnvironment instance; + static ILogger logger = new ConsoleLogger(); + readonly GrpcThreadPool threadPool; readonly CompletionRegistry completionRegistry; readonly DebugStats debugStats = new DebugStats(); @@ -92,18 +95,39 @@ namespace Grpc.Core } } + /// + /// Gets application-wide logger used by gRPC. + /// + /// The logger. + public static ILogger Logger + { + get + { + return logger; + } + } + + /// + /// Sets the application-wide logger that should be used by gRPC. + /// + public static void SetLogger(ILogger customLogger) + { + Preconditions.CheckNotNull(customLogger); + logger = customLogger; + } + /// /// Creates gRPC environment. /// private GrpcEnvironment() { - GrpcLog.RedirectNativeLogs(Console.Error); + NativeLogRedirector.Redirect(); grpcsharp_init(); completionRegistry = new CompletionRegistry(this); threadPool = new GrpcThreadPool(this, THREAD_POOL_SIZE); threadPool.Start(); // TODO: use proper logging here - Console.WriteLine("GRPC initialized."); + Logger.Info("gRPC initialized."); } /// @@ -154,8 +178,7 @@ namespace Grpc.Core debugStats.CheckOK(); - // TODO: use proper logging here - Console.WriteLine("GRPC shutdown."); + Logger.Info("gRPC shutdown."); } /// @@ -171,7 +194,7 @@ namespace Grpc.Core } catch (Exception e) { - Console.WriteLine("Error occured while shutting down GrpcEnvironment: " + e); + Logger.Error(e, "Error occured while shutting down GrpcEnvironment."); } }); } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 51022ac34f..bfcb9366a1 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core.Internal @@ -47,6 +48,8 @@ namespace Grpc.Core.Internal /// internal class AsyncCall : AsyncCallBase { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + Channel channel; // Completion of a pending unary response if not null. @@ -106,7 +109,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured while invoking completion delegate: " + e); + Logger.Error(e, "Exception occured while invoking completion delegate."); } } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 64713c8c52..38f2a5baeb 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core.Internal @@ -48,6 +49,8 @@ namespace Grpc.Core.Internal /// internal abstract class AsyncCallBase { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + readonly Func serializer; readonly Func deserializer; @@ -233,9 +236,9 @@ namespace Grpc.Core.Internal payload = serializer(msg); return true; } - catch (Exception) + catch (Exception e) { - Console.WriteLine("Exception occured while trying to serialize message"); + Logger.Error(e, "Exception occured while trying to serialize message"); payload = null; return false; } @@ -248,9 +251,9 @@ namespace Grpc.Core.Internal msg = deserializer(payload); return true; } - catch (Exception) + catch (Exception e) { - Console.WriteLine("Exception occured while trying to deserialize message"); + Logger.Error(e, "Exception occured while trying to deserialize message."); msg = default(TRead); return false; } @@ -264,7 +267,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured while invoking completion delegate: " + e); + Logger.Error(e, "Exception occured while invoking completion delegate."); } } diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs index f6d8aa0600..2796c959a3 100644 --- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs +++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs @@ -35,6 +35,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Runtime.InteropServices; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core.Internal @@ -45,6 +46,8 @@ namespace Grpc.Core.Internal internal class CompletionRegistry { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + readonly GrpcEnvironment environment; readonly ConcurrentDictionary dict = new ConcurrentDictionary(); @@ -81,7 +84,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured while invoking completion delegate: " + e); + Logger.Error(e, "Exception occured while invoking completion delegate."); } finally { diff --git a/src/csharp/Grpc.Core/Internal/GrpcLog.cs b/src/csharp/Grpc.Core/Internal/GrpcLog.cs deleted file mode 100644 index 2f3c8ad71c..0000000000 --- a/src/csharp/Grpc.Core/Internal/GrpcLog.cs +++ /dev/null @@ -1,94 +0,0 @@ -#region Copyright notice and license - -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#endregion - -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; - -namespace Grpc.Core.Internal -{ - internal delegate void GprLogDelegate(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr); - - /// - /// Logs from gRPC C core library can get lost if your application is not a console app. - /// This class allows redirection of logs to arbitrary destination. - /// - internal static class GrpcLog - { - static object staticLock = new object(); - static GprLogDelegate writeCallback; - static TextWriter dest; - - [DllImport("grpc_csharp_ext.dll")] - static extern void grpcsharp_redirect_log(GprLogDelegate callback); - - /// - /// Sets text writer as destination for logs from native gRPC C core library. - /// Only first invocation has effect. - /// - /// - public static void RedirectNativeLogs(TextWriter textWriter) - { - lock (staticLock) - { - if (writeCallback == null) - { - writeCallback = new GprLogDelegate(HandleWrite); - dest = textWriter; - grpcsharp_redirect_log(writeCallback); - } - } - } - - private static void HandleWrite(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr) - { - try - { - // TODO: DateTime format used here is different than in C core. - dest.WriteLine(string.Format("{0}{1} {2} {3}:{4}: {5}", - Marshal.PtrToStringAnsi(severityStringPtr), DateTime.Now, - threadId, - Marshal.PtrToStringAnsi(fileStringPtr), - line, - Marshal.PtrToStringAnsi(msgPtr))); - } - catch (Exception e) - { - Console.WriteLine("Caught exception in native callback " + e); - } - } - } -} diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs index b77e893044..cb4c7c821e 100644 --- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs +++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs @@ -36,7 +36,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using Grpc.Core.Internal; +using Grpc.Core.Logging; namespace Grpc.Core.Internal { @@ -45,6 +45,8 @@ namespace Grpc.Core.Internal /// internal class GrpcThreadPool { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + readonly GrpcEnvironment environment; readonly object myLock = new object(); readonly List threads = new List(); @@ -82,7 +84,7 @@ namespace Grpc.Core.Internal { cq.Shutdown(); - Console.WriteLine("Waiting for GRPC threads to finish."); + Logger.Info("Waiting for GRPC threads to finish."); foreach (var thread in threads) { thread.Join(); @@ -129,12 +131,12 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured while invoking completion delegate: " + e); + Logger.Error(e, "Exception occured while invoking completion delegate"); } } } while (ev.type != GRPCCompletionType.Shutdown); - Console.WriteLine("Completion queue has shutdown successfully, thread " + Thread.CurrentThread.Name + " exiting."); + Logger.Info("Completion queue has shutdown successfully, thread {0} exiting.", Thread.CurrentThread.Name); } } } diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs new file mode 100644 index 0000000000..b8a55c5fe8 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs @@ -0,0 +1,107 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Grpc.Core.Internal +{ + internal delegate void GprLogDelegate(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr); + + /// + /// Logs from gRPC C core library can get lost if your application is not a console app. + /// This class allows redirection of logs to gRPC logger. + /// + internal static class NativeLogRedirector + { + static object staticLock = new object(); + static GprLogDelegate writeCallback; + + [DllImport("grpc_csharp_ext.dll")] + static extern void grpcsharp_redirect_log(GprLogDelegate callback); + + /// + /// Redirects logs from native gRPC C core library to a general logger. + /// + public static void Redirect() + { + lock (staticLock) + { + if (writeCallback == null) + { + writeCallback = new GprLogDelegate(HandleWrite); + grpcsharp_redirect_log(writeCallback); + } + } + } + + private static void HandleWrite(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr) + { + try + { + var logger = GrpcEnvironment.Logger; + string severityString = Marshal.PtrToStringAnsi(severityStringPtr); + string message = string.Format("{0} {1}:{2}: {3}", + threadId, + Marshal.PtrToStringAnsi(fileStringPtr), + line, + Marshal.PtrToStringAnsi(msgPtr)); + + switch (severityString) + { + case "D": + logger.Debug(message); + break; + case "I": + logger.Info(message); + break; + case "E": + logger.Error(message); + break; + default: + // severity not recognized, default to error. + logger.Error(message); + break; + } + } + catch (Exception e) + { + Console.WriteLine("Caught exception in native callback " + e); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index 84ea346ebc..19f0e3c57f 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -37,6 +37,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core.Internal @@ -50,6 +51,8 @@ namespace Grpc.Core.Internal where TRequest : class where TResponse : class { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + readonly Method method; readonly UnaryServerMethod handler; @@ -85,7 +88,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured in handler: " + e); + Logger.Error(e, "Exception occured in handler."); status = HandlerUtils.StatusFromException(e); } try @@ -104,6 +107,8 @@ namespace Grpc.Core.Internal where TRequest : class where TResponse : class { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + readonly Method method; readonly ServerStreamingServerMethod handler; @@ -138,7 +143,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured in handler: " + e); + Logger.Error(e, "Exception occured in handler."); status = HandlerUtils.StatusFromException(e); } @@ -158,6 +163,8 @@ namespace Grpc.Core.Internal where TRequest : class where TResponse : class { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + readonly Method method; readonly ClientStreamingServerMethod handler; @@ -196,7 +203,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured in handler: " + e); + Logger.Error(e, "Exception occured in handler."); status = HandlerUtils.StatusFromException(e); } @@ -216,6 +223,8 @@ namespace Grpc.Core.Internal where TRequest : class where TResponse : class { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + readonly Method method; readonly DuplexStreamingServerMethod handler; @@ -246,7 +255,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Console.WriteLine("Exception occured in handler: " + e); + Logger.Error(e, "Exception occured in handler."); status = HandlerUtils.StatusFromException(e); } try diff --git a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs new file mode 100644 index 0000000000..c67765c78d --- /dev/null +++ b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs @@ -0,0 +1,103 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; + +namespace Grpc.Core.Logging +{ + /// Logger that logs to System.Console. + public class ConsoleLogger : ILogger + { + readonly Type forType; + readonly string forTypeString; + + public ConsoleLogger() : this(null) + { + } + + private ConsoleLogger(Type forType) + { + this.forType = forType; + this.forTypeString = forType != null ? forType.FullName + " " : ""; + } + + public ILogger ForType() + { + if (typeof(T) == forType) + { + return this; + } + return new ConsoleLogger(typeof(T)); + } + + public void Debug(string message, params object[] formatArgs) + { + Log("D", message, formatArgs); + } + + public void Info(string message, params object[] formatArgs) + { + Log("I", message, formatArgs); + } + + public void Warning(string message, params object[] formatArgs) + { + Log("W", message, formatArgs); + } + + public void Warning(Exception exception, string message, params object[] formatArgs) + { + Log("W", message + " " + exception, formatArgs); + } + + public void Error(string message, params object[] formatArgs) + { + Log("E", message, formatArgs); + } + + public void Error(Exception exception, string message, params object[] formatArgs) + { + Log("E", message + " " + exception, formatArgs); + } + + private void Log(string severityString, string message, object[] formatArgs) + { + Console.Error.WriteLine("{0}{1} {2}{3}", + severityString, + DateTime.Now, + forTypeString, + string.Format(message, formatArgs)); + } + } +} diff --git a/src/csharp/Grpc.Core/Logging/ILogger.cs b/src/csharp/Grpc.Core/Logging/ILogger.cs new file mode 100644 index 0000000000..0d58f133e3 --- /dev/null +++ b/src/csharp/Grpc.Core/Logging/ILogger.cs @@ -0,0 +1,57 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; + +namespace Grpc.Core.Logging +{ + /// For logging messages. + public interface ILogger + { + /// Returns a logger associated with the specified type. + ILogger ForType(); + + void Debug(string message, params object[] formatArgs); + + void Info(string message, params object[] formatArgs); + + void Warning(string message, params object[] formatArgs); + + void Warning(Exception exception, string message, params object[] formatArgs); + + void Error(string message, params object[] formatArgs); + + void Error(Exception exception, string message, params object[] formatArgs); + } +} diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index fd30735359..d80e3d624f 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -38,6 +38,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core @@ -52,6 +53,8 @@ namespace Grpc.Core /// public const int PickUnusedPort = 0; + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + readonly GrpcEnvironment environment; readonly List options; readonly ServerSafeHandle handle; @@ -233,7 +236,7 @@ namespace Grpc.Core } catch (Exception e) { - Console.WriteLine("Exception while handling RPC: " + e); + Logger.Warning(e, "Exception while handling RPC."); } } diff --git a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs index 4180d98938..82653c3a1f 100644 --- a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs +++ b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs @@ -46,13 +46,15 @@ namespace Grpc.Core.Utils /// public static void RunBenchmark(int warmupIterations, int benchmarkIterations, Action action) { - Console.WriteLine("Warmup iterations: " + warmupIterations); + var logger = GrpcEnvironment.Logger; + + logger.Info("Warmup iterations: {0}", warmupIterations); for (int i = 0; i < warmupIterations; i++) { action(); } - Console.WriteLine("Benchmark iterations: " + benchmarkIterations); + logger.Info("Benchmark iterations: {0}", benchmarkIterations); var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < benchmarkIterations; i++) @@ -60,8 +62,8 @@ namespace Grpc.Core.Utils action(); } stopwatch.Stop(); - Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms"); - Console.WriteLine("Ops per second: " + (int)((double)benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds)); + logger.Info("Elapsed time: {0}ms", stopwatch.ElapsedMilliseconds); + logger.Info("Ops per second: {0}", (int)((double)benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds)); } } } diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index b2397d4e23..2d841a9c11 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -62,7 +62,7 @@ namespace Grpc.IntegrationTesting File.ReadAllText(TestCredentials.ServerCertChainPath), File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); - var serverCredentials = new SslServerCredentials(new [] { keyCertPair }, rootCert); + var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert); var clientCredentials = new SslCredentials(rootCert, keyCertPair); server = new Server(); @@ -93,6 +93,5 @@ namespace Grpc.IntegrationTesting var response = client.UnaryCall(SimpleRequest.CreateBuilder().SetResponseSize(10).Build()); Assert.AreEqual(10, response.Payload.Body.Length); } - } } -- cgit v1.2.3