http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 59bf090..db2a96b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -308,7 +308,6 @@ <Compile Include="Impl\Common\IgniteConfigurationXmlSerializer.cs" /> <Compile Include="Impl\Common\IgniteHome.cs" /> <Compile Include="Impl\Common\LoadedAssembliesResolver.cs" /> - <Compile Include="Impl\Common\Logger.cs" /> <Compile Include="Impl\Common\ResizeableArray.cs" /> <Compile Include="Impl\Common\TypeCaster.cs" /> <Compile Include="Impl\Common\TypeStringConverter.cs" /> @@ -343,6 +342,7 @@ <Compile Include="Impl\Ignite.cs" /> <Compile Include="Impl\IgniteManager.cs" /> <Compile Include="Impl\IgniteProxy.cs" /> + <Compile Include="Impl\Log\JavaLogger.cs" /> <Compile Include="Impl\PlatformTarget.cs" /> <Compile Include="Impl\IgniteUtils.cs" /> <Compile Include="Impl\Handle\Handle.cs" /> @@ -435,6 +435,10 @@ <Compile Include="Interop\Package-Info.cs" /> <Compile Include="Lifecycle\ClientReconnectEventArgs.cs" /> <Compile Include="Lifecycle\Package-Info.cs" /> + <Compile Include="Log\CategoryLogger.cs" /> + <Compile Include="Log\ILogger.cs" /> + <Compile Include="Log\LoggerExtensions.cs" /> + <Compile Include="Log\LogLevel.cs" /> <Compile Include="Messaging\Package-Info.cs" /> <Compile Include="Package-Info.cs" /> <Compile Include="Lifecycle\ILifecycleBean.cs" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs index e5e79cd..cb15564 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs @@ -23,6 +23,7 @@ namespace Apache.Ignite.Core.Cache.Configuration using System; using System.Collections.Generic; using System.ComponentModel; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using Apache.Ignite.Core.Binary; @@ -35,6 +36,7 @@ namespace Apache.Ignite.Core.Cache.Configuration using Apache.Ignite.Core.Common; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Cache.Affinity; + using Apache.Ignite.Core.Log; /// <summary> /// Defines grid cache configuration. @@ -353,6 +355,21 @@ namespace Apache.Ignite.Core.Cache.Configuration } /// <summary> + /// Validates this instance and outputs information to the log, if necessary. + /// </summary> + internal void Validate(ILogger log) + { + Debug.Assert(log != null); + + var entities = QueryEntities; + if (entities != null) + { + foreach (var entity in entities) + entity.Validate(log, string.Format("Validating cache configuration '{0}'", Name ?? "")); + } + } + + /// <summary> /// Gets or sets write synchronization mode. This mode controls whether the main /// caller should wait for update on other nodes to complete or not. /// </summary> @@ -669,7 +686,7 @@ namespace Apache.Ignite.Core.Cache.Configuration /// <summary> /// Gets or sets the affinity function to provide mapping from keys to nodes. /// <para /> - /// Predefined implementations: + /// Predefined implementations: /// <see cref="RendezvousAffinityFunction"/>, <see cref="FairAffinityFunction"/>. /// </summary> public IAffinityFunction AffinityFunction { get; set; } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs index e6eceb8..adfe9e1 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs @@ -27,6 +27,7 @@ namespace Apache.Ignite.Core.Cache.Configuration using System.Reflection; using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Impl.Binary; + using Apache.Ignite.Core.Log; /// <summary> /// Query entity is a description of cache entry (composed of key and value) @@ -104,7 +105,7 @@ namespace Apache.Ignite.Core.Cache.Configuration KeyTypeName = value == null ? null - : (JavaTypes.GetJavaTypeNameAndLogWarning(value) ?? BinaryUtils.GetTypeName(value)); + : (JavaTypes.GetJavaTypeName(value) ?? BinaryUtils.GetTypeName(value)); _keyType = value; } @@ -140,7 +141,7 @@ namespace Apache.Ignite.Core.Cache.Configuration ValueTypeName = value == null ? null - : (JavaTypes.GetJavaTypeNameAndLogWarning(value) ?? BinaryUtils.GetTypeName(value)); + : (JavaTypes.GetJavaTypeName(value) ?? BinaryUtils.GetTypeName(value)); _valueType = value; } @@ -239,6 +240,26 @@ namespace Apache.Ignite.Core.Cache.Configuration writer.WriteInt(0); } + /// <summary> + /// Validates this instance and outputs information to the log, if necessary. + /// </summary> + internal void Validate(ILogger log, string logInfo) + { + Debug.Assert(log != null); + Debug.Assert(logInfo != null); + + logInfo += string.Format(", QueryEntity '{0}:{1}'", _keyTypeName ?? "", _valueTypeName ?? ""); + + JavaTypes.LogIndirectMappingWarning(_keyType, log, logInfo); + JavaTypes.LogIndirectMappingWarning(_valueType, log, logInfo); + + var fields = Fields; + if (fields != null) + { + foreach (var field in fields) + field.Validate(log, logInfo); + } + } /// <summary> /// Rescans the attributes in <see cref="KeyType"/> and <see cref="ValueType"/>. http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs index b11e53d..12028e2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs @@ -20,8 +20,10 @@ namespace Apache.Ignite.Core.Cache.Configuration { using System; + using System.Diagnostics; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Common; + using Apache.Ignite.Core.Log; /// <summary> /// Represents a queryable field. @@ -71,7 +73,7 @@ namespace Apache.Ignite.Core.Cache.Configuration } /// <summary> - /// Gets the field name. + /// Gets or sets the field name. /// </summary> public string Name { get; set; } @@ -87,7 +89,7 @@ namespace Apache.Ignite.Core.Cache.Configuration { FieldTypeName = value == null ? null - : (JavaTypes.GetJavaTypeNameAndLogWarning(value) ?? BinaryUtils.GetTypeName(value)); + : (JavaTypes.GetJavaTypeName(value) ?? BinaryUtils.GetTypeName(value)); _type = value; } @@ -105,5 +107,18 @@ namespace Apache.Ignite.Core.Cache.Configuration _type = null; } } + + /// <summary> + /// Validates this instance and outputs information to the log, if necessary. + /// </summary> + internal void Validate(ILogger log, string logInfo) + { + Debug.Assert(log != null); + Debug.Assert(logInfo != null); + + logInfo += string.Format(", QueryField '{0}'", Name); + + JavaTypes.LogIndirectMappingWarning(_type, log, logInfo); + } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs index a16ae3a..91aa1dd 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs @@ -29,6 +29,7 @@ namespace Apache.Ignite.Core using Apache.Ignite.Core.Datastream; using Apache.Ignite.Core.DataStructures; using Apache.Ignite.Core.Events; + using Apache.Ignite.Core.Log; using Apache.Ignite.Core.Lifecycle; using Apache.Ignite.Core.Messaging; using Apache.Ignite.Core.Services; @@ -277,6 +278,13 @@ namespace Apache.Ignite.Core ICollection<string> GetCacheNames(); /// <summary> + /// Gets the logger. + /// <para /> + /// See <see cref="IgniteConfiguration.Logger"/> for customization. + /// </summary> + ILogger Logger { get; } + + /// <summary> /// Occurs when node begins to stop. Node is fully functional at this point. /// See also: <see cref="LifecycleEventType.BeforeNodeStop"/>. /// </summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs index 6bdf1ab..8e16fb5 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs @@ -38,6 +38,7 @@ using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Lifecycle; + using Apache.Ignite.Core.Log; using Apache.Ignite.Core.Transactions; using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader; using BinaryWriter = Apache.Ignite.Core.Impl.Binary.BinaryWriter; @@ -292,6 +293,21 @@ } /// <summary> + /// Validates this instance and outputs information to the log, if necessary. + /// </summary> + internal void Validate(ILogger log) + { + Debug.Assert(log != null); + + var ccfg = CacheConfiguration; + if (ccfg != null) + { + foreach (var cfg in ccfg) + cfg.Validate(log); + } + } + + /// <summary> /// Reads data from specified reader into current instance. /// </summary> /// <param name="r">The binary reader.</param> @@ -398,6 +414,7 @@ Assemblies = cfg.Assemblies; SuppressWarnings = cfg.SuppressWarnings; LifecycleBeans = cfg.LifecycleBeans; + Logger = cfg.Logger; JvmInitialMemoryMb = cfg.JvmInitialMemoryMb; JvmMaxMemoryMb = cfg.JvmMaxMemoryMb; } @@ -678,5 +695,76 @@ get { return _isLateAffinityAssignment ?? DefaultIsLateAffinityAssignment; } set { _isLateAffinityAssignment = value; } } + + /// <summary> + /// Serializes this instance to the specified XML writer. + /// </summary> + /// <param name="writer">The writer.</param> + /// <param name="rootElementName">Name of the root element.</param> + public void ToXml(XmlWriter writer, string rootElementName) + { + IgniteArgumentCheck.NotNull(writer, "writer"); + IgniteArgumentCheck.NotNullOrEmpty(rootElementName, "rootElementName"); + + IgniteConfigurationXmlSerializer.Serialize(this, writer, rootElementName); + } + + /// <summary> + /// Serializes this instance to an XML string. + /// </summary> + public string ToXml() + { + var sb = new StringBuilder(); + + var settings = new XmlWriterSettings + { + Indent = true + }; + + using (var xmlWriter = XmlWriter.Create(sb, settings)) + { + ToXml(xmlWriter, "igniteConfiguration"); + } + + return sb.ToString(); + } + + /// <summary> + /// Deserializes IgniteConfiguration from the XML reader. + /// </summary> + /// <param name="reader">The reader.</param> + /// <returns>Deserialized instance.</returns> + public static IgniteConfiguration FromXml(XmlReader reader) + { + IgniteArgumentCheck.NotNull(reader, "reader"); + + return IgniteConfigurationXmlSerializer.Deserialize(reader); + } + + /// <summary> + /// Deserializes IgniteConfiguration from the XML string. + /// </summary> + /// <param name="xml">Xml string.</param> + /// <returns>Deserialized instance.</returns> + public static IgniteConfiguration FromXml(string xml) + { + IgniteArgumentCheck.NotNullOrEmpty(xml, "xml"); + + using (var xmlReader = XmlReader.Create(new StringReader(xml))) + { + // Skip XML header. + xmlReader.MoveToContent(); + + return FromXml(xmlReader); + } + } + + /// <summary> + /// Gets or sets the logger. + /// <para /> + /// If no logger is set, logging is delegated to Java, which uses the logger defined in Spring XML (if present) + /// or logs to console otherwise. + /// </summary> + public ILogger Logger { get; set; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd index 24eaa30..916fd20 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd @@ -357,6 +357,18 @@ <xs:attribute name="pessimisticTransactionLogLinger" type="xs:string" /> </xs:complexType> </xs:element> + <xs:element name="logger" minOccurs="0"> + <xs:annotation> + <xs:documentation>The logger. If no logger is set, logging is delegated to Java, which uses the logger defined in Spring XML (if present) or logs to console otherwise.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:attribute name="type" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation>Assembly-qualified type name.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> </xs:all> <xs:attribute name="gridName" type="xs:string" /> <xs:attribute name="jvmDllPath" type="xs:string" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs index 552a7f2..7b023f3 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs @@ -35,9 +35,11 @@ namespace Apache.Ignite.Core using Apache.Ignite.Core.Impl.Cache.Affinity; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Impl.Handle; + using Apache.Ignite.Core.Impl.Log; using Apache.Ignite.Core.Impl.Memory; using Apache.Ignite.Core.Impl.Unmanaged; using Apache.Ignite.Core.Lifecycle; + using Apache.Ignite.Core.Log; using Apache.Ignite.Core.Resource; using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader; using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils; @@ -201,15 +203,21 @@ namespace Apache.Ignite.Core lock (SyncRoot) { + // 0. Init logger + var log = cfg.Logger ?? new JavaLogger(); + + log.Debug("Starting Ignite.NET " + Assembly.GetExecutingAssembly().GetName().Version); + // 1. Check GC settings. - CheckServerGc(cfg); + CheckServerGc(cfg, log); // 2. Create context. - IgniteUtils.LoadDlls(cfg.JvmDllPath); + IgniteUtils.LoadDlls(cfg.JvmDllPath, log); - var cbs = new UnmanagedCallbacks(); + var cbs = new UnmanagedCallbacks(log); - IgniteManager.CreateJvmContext(cfg, cbs); + IgniteManager.CreateJvmContext(cfg, cbs, log); + log.Debug("JVM started."); var gridName = cfg.GridName; @@ -221,12 +229,17 @@ namespace Apache.Ignite.Core try { // 4. Initiate Ignite start. - UU.IgnitionStart(cbs.Context, cfg.SpringConfigUrl, gridName, ClientMode); + UU.IgnitionStart(cbs.Context, cfg.SpringConfigUrl, gridName, ClientMode, cfg.Logger != null); + // 5. At this point start routine is finished. We expect STARTUP object to have all necessary data. var node = _startup.Ignite; interopProc = node.InteropProcessor; + var javaLogger = log as JavaLogger; + if (javaLogger != null) + javaLogger.SetProcessor(interopProc); + // 6. On-start callback (notify lifecycle components). node.OnStart(); @@ -271,10 +284,11 @@ namespace Apache.Ignite.Core /// Check whether GC is set to server mode. /// </summary> /// <param name="cfg">Configuration.</param> - private static void CheckServerGc(IgniteConfiguration cfg) + /// <param name="log">Log.</param> + private static void CheckServerGc(IgniteConfiguration cfg, ILogger log) { if (!cfg.SuppressWarnings && !GCSettings.IsServerGC && Interlocked.CompareExchange(ref _gcWarn, 1, 0) == 0) - Logger.LogWarning("GC server mode is not enabled, this could lead to less " + + log.Warn("GC server mode is not enabled, this could lead to less " + "than optimal performance on multi-core machines (to enable see " + "http://msdn.microsoft.com/en-us/library/ms229357(v=vs.110).aspx)."); } @@ -285,14 +299,15 @@ namespace Apache.Ignite.Core /// <param name="inStream">Input stream with data.</param> /// <param name="outStream">Output stream.</param> /// <param name="handleRegistry">Handle registry.</param> - internal static void OnPrepare(PlatformMemoryStream inStream, PlatformMemoryStream outStream, - HandleRegistry handleRegistry) + /// <param name="log">Log.</param> + internal static void OnPrepare(PlatformMemoryStream inStream, PlatformMemoryStream outStream, + HandleRegistry handleRegistry, ILogger log) { try { BinaryReader reader = BinaryUtils.Marshaller.StartUnmarshal(inStream); - PrepareConfiguration(reader, outStream); + PrepareConfiguration(reader, outStream, log); PrepareLifecycleBeans(reader, outStream, handleRegistry); @@ -313,7 +328,8 @@ namespace Apache.Ignite.Core /// </summary> /// <param name="reader">Reader.</param> /// <param name="outStream">Response stream.</param> - private static void PrepareConfiguration(BinaryReader reader, PlatformMemoryStream outStream) + /// <param name="log">Log.</param> + private static void PrepareConfiguration(BinaryReader reader, PlatformMemoryStream outStream, ILogger log) { // 1. Load assemblies. IgniteConfiguration cfg = _startup.Configuration; @@ -334,6 +350,7 @@ namespace Apache.Ignite.Core _startup.Marshaller = new Marshaller(cfg.BinaryConfiguration); // 3. Send configuration details to Java + cfg.Validate(log); cfg.Write(_startup.Marshaller.StartMarshal(outStream)); } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/JavaTypes.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/JavaTypes.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/JavaTypes.cs index f30264d..a8d94f2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/JavaTypes.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/JavaTypes.cs @@ -20,7 +20,7 @@ namespace Apache.Ignite.Core.Impl.Binary using System; using System.Collections.Generic; using System.Linq; - using Apache.Ignite.Core.Impl.Common; + using Apache.Ignite.Core.Log; /// <summary> /// Provides mapping between Java and .NET basic types. @@ -67,26 +67,33 @@ namespace Apache.Ignite.Core.Impl.Binary /// <summary> /// Gets the corresponding Java type name. - /// Logs a warning for indirectly mapped types. /// </summary> - public static string GetJavaTypeNameAndLogWarning(Type type) + public static string GetJavaTypeName(Type type) { if (type == null) return null; string res; - if (!NetToJava.TryGetValue(type, out res)) - return null; + return NetToJava.TryGetValue(type, out res) ? res : null; + } - Type directType; + /// <summary> + /// Logs a warning for indirectly mapped types. + /// </summary> + public static void LogIndirectMappingWarning(Type type, ILogger log, string logInfo) + { + if (type == null) + return; - if (IndirectMappingTypes.TryGetValue(type, out directType)) - Logger.LogWarning("Type '{0}' maps to Java type '{1}' using unchecked conversion. " + - "This may cause issues in SQL queries. " + - "You can use '{2}' instead to achieve direct mapping.", type, res, directType); + Type directType; + if (!IndirectMappingTypes.TryGetValue(type, out directType)) + return; - return res; + log.Warn("{0}: Type '{1}' maps to Java type '{2}' using unchecked conversion. " + + "This may cause issues in SQL queries. " + + "You can use '{3}' instead to achieve direct mapping.", + logInfo, type, NetToJava[type], directType); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Logger.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Logger.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Logger.cs deleted file mode 100644 index cab5afc..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Logger.cs +++ /dev/null @@ -1,37 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF 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 Apache.Ignite.Core.Impl.Common -{ - using System; - - /// <summary> - /// Console logger. - /// </summary> - internal static class Logger - { - /// <summary> - /// Logs the warning. - /// </summary> - /// <param name="warning">The warning.</param> - /// <param name="args">The arguments.</param> - public static void LogWarning(string warning, params object[] args) - { - Console.WriteLine("WARNING: " + string.Format(warning, args)); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs index 0fac417..2a3a014 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs @@ -43,6 +43,7 @@ namespace Apache.Ignite.Core.Impl using Apache.Ignite.Core.Impl.Transactions; using Apache.Ignite.Core.Impl.Unmanaged; using Apache.Ignite.Core.Lifecycle; + using Apache.Ignite.Core.Log; using Apache.Ignite.Core.Messaging; using Apache.Ignite.Core.Services; using Apache.Ignite.Core.Transactions; @@ -407,6 +408,7 @@ namespace Apache.Ignite.Core.Impl NearCacheConfiguration nearConfiguration) { IgniteArgumentCheck.NotNull(configuration, "configuration"); + configuration.Validate(Logger); using (var stream = IgniteManager.Memory.Allocate().GetStream()) { @@ -445,6 +447,7 @@ namespace Apache.Ignite.Core.Impl NearCacheConfiguration nearConfiguration) { IgniteArgumentCheck.NotNull(configuration, "configuration"); + configuration.Validate(Logger); using (var stream = IgniteManager.Memory.Allocate().GetStream()) { @@ -674,6 +677,12 @@ namespace Apache.Ignite.Core.Impl } /** <inheritdoc /> */ + public ILogger Logger + { + get { return _cbs.Log; } + } + + /** <inheritdoc /> */ public event EventHandler Stopping; /** <inheritdoc /> */ http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs index 05bc786..ee54218 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs @@ -27,6 +27,7 @@ namespace Apache.Ignite.Core.Impl using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Impl.Memory; using Apache.Ignite.Core.Impl.Unmanaged; + using Apache.Ignite.Core.Log; using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils; /// <summary> @@ -57,8 +58,9 @@ namespace Apache.Ignite.Core.Impl /// </summary> /// <param name="cfg">Configuration.</param> /// <param name="cbs">Callbacks.</param> + /// <param name="log"></param> /// <returns>Context.</returns> - internal static void CreateJvmContext(IgniteConfiguration cfg, UnmanagedCallbacks cbs) + internal static void CreateJvmContext(IgniteConfiguration cfg, UnmanagedCallbacks cbs, ILogger log) { lock (SyncRoot) { @@ -69,7 +71,7 @@ namespace Apache.Ignite.Core.Impl { if (!_jvmCfg.Equals(jvmCfg)) { - Logger.LogWarning("Attempting to start Ignite node with different Java " + + log.Warn("Attempting to start Ignite node with different Java " + "configuration; current Java configuration will be ignored (consider " + "starting node in separate process) [oldConfig=" + _jvmCfg + ", newConfig=" + jvmCfg + ']'); http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs index 12de847..914a87d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs @@ -31,6 +31,7 @@ namespace Apache.Ignite.Core.Impl using Apache.Ignite.Core.Events; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Cluster; + using Apache.Ignite.Core.Log; using Apache.Ignite.Core.Lifecycle; using Apache.Ignite.Core.Messaging; using Apache.Ignite.Core.Services; @@ -392,6 +393,12 @@ namespace Apache.Ignite.Core.Impl } /** <inheritdoc /> */ + public ILogger Logger + { + get { return _ignite.Logger; } + } + + /** <inheritdoc /> */ public event EventHandler Stopping { add { _ignite.Stopping += value; } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteUtils.cs index 048c8ac..70d483d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteUtils.cs @@ -35,6 +35,7 @@ namespace Apache.Ignite.Core.Impl using Apache.Ignite.Core.Impl.Cluster; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Impl.Unmanaged; + using Apache.Ignite.Core.Log; using Microsoft.Win32; using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader; @@ -124,12 +125,17 @@ namespace Apache.Ignite.Core.Impl /// Load JVM DLL if needed. /// </summary> /// <param name="configJvmDllPath">JVM DLL path from config.</param> - public static void LoadDlls(string configJvmDllPath) + /// <param name="log">Log.</param> + public static void LoadDlls(string configJvmDllPath, ILogger log) { - if (_loaded) return; + if (_loaded) + { + log.Debug("JNI dll is already loaded."); + return; + } // 1. Load JNI dll. - LoadJvmDll(configJvmDllPath); + LoadJvmDll(configJvmDllPath, log); // 2. Load GG JNI dll. UnmanagedUtils.Initialize(); @@ -190,17 +196,25 @@ namespace Apache.Ignite.Core.Impl /// <summary> /// Loads the JVM DLL. /// </summary> - private static void LoadJvmDll(string configJvmDllPath) + private static void LoadJvmDll(string configJvmDllPath, ILogger log) { var messages = new List<string>(); foreach (var dllPath in GetJvmDllPaths(configJvmDllPath)) { + log.Debug("Trying to load JVM dll from [option={0}, path={1}]...", dllPath.Key, dllPath.Value); + var errCode = LoadDll(dllPath.Value, FileJvmDll); if (errCode == 0) + { + log.Debug("jvm.dll successfully loaded from [option={0}, path={1}]", dllPath.Key, dllPath.Value); return; + } + + var message = string.Format(CultureInfo.InvariantCulture, "[option={0}, path={1}, error={2}]", + dllPath.Key, dllPath.Value, FormatWin32Error(errCode)); + messages.Add(message); - messages.Add(string.Format(CultureInfo.InvariantCulture, "[option={0}, path={1}, error={2}]", - dllPath.Key, dllPath.Value, FormatWin32Error(errCode))); + log.Debug("Failed to load jvm.dll: " + message); if (dllPath.Value == configJvmDllPath) break; // if configJvmDllPath is specified and is invalid - do not try other options http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Log/JavaLogger.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Log/JavaLogger.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Log/JavaLogger.cs new file mode 100644 index 0000000..23e7a37 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Log/JavaLogger.cs @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 Apache.Ignite.Core.Impl.Log +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using Apache.Ignite.Core.Impl.Unmanaged; + using Apache.Ignite.Core.Log; + + /// <summary> + /// Logger that delegates to Java. + /// </summary> + internal class JavaLogger : ILogger + { + /** */ + private IUnmanagedTarget _proc; + + /** */ + private readonly List<LogLevel> _enabledLevels = new List<LogLevel>(5); + + /** */ + private readonly List<Tuple<LogLevel, string, string, string>> _pendingLogs + = new List<Tuple<LogLevel, string, string, string>>(); + + /** */ + private readonly object _syncRoot = new object(); + + /// <summary> + /// Sets the processor. + /// </summary> + /// <param name="proc">The proc.</param> + public void SetProcessor(IUnmanagedTarget proc) + { + Debug.Assert(proc != null); + + lock (_syncRoot) + { + _proc = proc; + + // Preload enabled levels. + _enabledLevels.AddRange( + new[] { LogLevel.Trace, LogLevel.Debug, LogLevel.Info, LogLevel.Warn, LogLevel.Error } + .Where(x => UnmanagedUtils.ProcessorLoggerIsLevelEnabled(proc, (int)x))); + + foreach (var log in _pendingLogs) + { + Log(log.Item1, log.Item2, log.Item3, log.Item4); + } + } + } + + /** <inheritdoc /> */ + public void Log(LogLevel level, string message, object[] args, IFormatProvider formatProvider, string category, + string nativeErrorInfo, Exception ex) + { + // Java error info should not go back to Java. + // Either we log in .NET, and Java sends us logs, or we log in Java, and .NET sends logs, not both. + Debug.Assert(nativeErrorInfo == null); + + lock (_syncRoot) + { + if (!IsEnabled(level)) + return; + + var msg = args == null ? message : string.Format(formatProvider, message, args); + var err = ex != null ? ex.ToString() : null; + + if (_proc != null) + Log(level, msg, category, err); + else + _pendingLogs.Add(Tuple.Create(level, msg, category, err)); + } + } + + /** <inheritdoc /> */ + public bool IsEnabled(LogLevel level) + { + lock (_syncRoot) + { + return _proc == null || _enabledLevels.Contains(level); + } + } + + /// <summary> + /// Logs the message. + /// </summary> + private void Log(LogLevel level, string msg, string category, string err) + { + if (IsEnabled(level)) + UnmanagedUtils.ProcessorLoggerLog(_proc, (int)level, msg, category, err); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/IgniteJniNativeMethods.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/IgniteJniNativeMethods.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/IgniteJniNativeMethods.cs index 2da4192..8756dec 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/IgniteJniNativeMethods.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/IgniteJniNativeMethods.cs @@ -113,6 +113,13 @@ namespace Apache.Ignite.Core.Impl.Unmanaged [DllImport(IgniteUtils.FileIgniteJniDll, EntryPoint = "IgniteProcessorGetCacheNames")] public static extern void ProcessorGetCacheNames(void* ctx, void* obj, long memPtr); + [DllImport(IgniteUtils.FileIgniteJniDll, EntryPoint = "IgniteProcessorLoggerIsLevelEnabled")] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool ProcessorLoggerIsLevelEnabled(void* ctx, void* obj, int level); + + [DllImport(IgniteUtils.FileIgniteJniDll, EntryPoint = "IgniteProcessorLoggerLog")] + public static extern void ProcessorLoggerLog(void* ctx, void* obj, int level, sbyte* messsage, sbyte* category, sbyte* errorInfo); + [DllImport(IgniteUtils.FileIgniteJniDll, EntryPoint = "IgniteTargetInStreamOutLong")] public static extern long TargetInStreamOutLong(void* ctx, void* target, int opType, long memPtr); http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs index 51d9c74..6367e1e 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs @@ -104,5 +104,8 @@ namespace Apache.Ignite.Core.Impl.Unmanaged internal void* affinityFunctionAssignPartitions; internal void* affinityFunctionRemoveNode; internal void* affinityFunctionDestroy; + + internal void* loggerLog; + internal void* loggerIsLevelEnabled; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs index 223eb5b..493e061 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs @@ -22,6 +22,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; + using System.Globalization; using System.Runtime.InteropServices; using System.Threading; using Apache.Ignite.Core.Cache.Affinity; @@ -38,11 +39,13 @@ namespace Apache.Ignite.Core.Impl.Unmanaged using Apache.Ignite.Core.Impl.Datastream; using Apache.Ignite.Core.Impl.Events; using Apache.Ignite.Core.Impl.Handle; + using Apache.Ignite.Core.Impl.Log; using Apache.Ignite.Core.Impl.Memory; using Apache.Ignite.Core.Impl.Messaging; using Apache.Ignite.Core.Impl.Resource; using Apache.Ignite.Core.Impl.Services; using Apache.Ignite.Core.Lifecycle; + using Apache.Ignite.Core.Log; using Apache.Ignite.Core.Services; using UU = UnmanagedUtils; @@ -89,6 +92,9 @@ namespace Apache.Ignite.Core.Impl.Unmanaged [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] private readonly IntPtr _cbsPtr; + /** Log. */ + private readonly ILogger _log; + /** Error type: generic. */ private const int ErrGeneric = 1; @@ -98,7 +104,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged /** Error type: attach. */ private const int ErrJvmAttach = 3; - /** Opeartion: prepare .Net. */ + /** Operation: prepare .Net. */ private const int OpPrepareDotNet = 1; private delegate long CacheStoreCreateCallbackDelegate(void* target, long memPtr); @@ -174,6 +180,9 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private delegate void OnClientDisconnectedDelegate(void* target); private delegate void OnClientReconnectedDelegate(void* target, bool clusterRestarted); + private delegate void LoggerLogDelegate(void* target, int level, sbyte* messageChars, int messageCharsLen, sbyte* categoryChars, int categoryCharsLen, sbyte* errorInfoChars, int errorInfoCharsLen, long memPtr); + private delegate bool LoggerIsLevelEnabledDelegate(void* target, int level); + private delegate long AffinityFunctionInitDelegate(void* target, long memPtr, void* baseFunc); private delegate int AffinityFunctionPartitionDelegate(void* target, long ptr, long memPtr); private delegate void AffinityFunctionAssignPartitionsDelegate(void* target, long ptr, long inMemPtr, long outMemPtr); @@ -183,10 +192,14 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private delegate void ConsoleWriteDelegate(sbyte* chars, int charsLen, bool isErr); /// <summary> - /// constructor. + /// Constructor. /// </summary> - public UnmanagedCallbacks() + /// <param name="log">Logger.</param> + public UnmanagedCallbacks(ILogger log) { + Debug.Assert(log != null); + _log = log; + var cbs = new UnmanagedCallbackHandlers { target = IntPtr.Zero.ToPointer(), // Target is not used in .Net as we rely on dynamic FP creation. @@ -270,7 +283,10 @@ namespace Apache.Ignite.Core.Impl.Unmanaged affinityFunctionPartition = CreateFunctionPointer((AffinityFunctionPartitionDelegate)AffinityFunctionPartition), affinityFunctionAssignPartitions = CreateFunctionPointer((AffinityFunctionAssignPartitionsDelegate)AffinityFunctionAssignPartitions), affinityFunctionRemoveNode = CreateFunctionPointer((AffinityFunctionRemoveNodeDelegate)AffinityFunctionRemoveNode), - affinityFunctionDestroy = CreateFunctionPointer((AffinityFunctionDestroyDelegate)AffinityFunctionDestroy) + affinityFunctionDestroy = CreateFunctionPointer((AffinityFunctionDestroyDelegate)AffinityFunctionDestroy), + + loggerLog = CreateFunctionPointer((LoggerLogDelegate)LoggerLog), + loggerIsLevelEnabled = CreateFunctionPointer((LoggerIsLevelEnabledDelegate)LoggerIsLevelEnabled) }; _cbsPtr = Marshal.AllocHGlobal(UU.HandlersSize()); @@ -550,7 +566,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged } /// <summary> - /// Get comptue job using it's GC handle pointer. + /// Get compute job using it's GC handle pointer. /// </summary> /// <param name="jobPtr">Job pointer.</param> /// <returns>Compute job.</returns> @@ -883,7 +899,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged using (var inStream = IgniteManager.Memory.Get(arg1).GetStream()) using (var outStream = IgniteManager.Memory.Get(arg2).GetStream()) { - Ignition.OnPrepare(inStream, outStream, _handleRegistry); + Ignition.OnPrepare(inStream, outStream, _handleRegistry, _log); return 0; } @@ -1131,6 +1147,40 @@ namespace Apache.Ignite.Core.Impl.Unmanaged }); } + private void LoggerLog(void* target, int level, sbyte* messageChars, int messageCharsLen, sbyte* categoryChars, + int categoryCharsLen, sbyte* errorInfoChars, int errorInfoCharsLen, long memPtr) + { + // When custom logger in .NET is not defined, Java should not call us. + Debug.Assert(!(_log is JavaLogger)); + + SafeCall(() => + { + var message = IgniteUtils.Utf8UnmanagedToString(messageChars, messageCharsLen); + var category = IgniteUtils.Utf8UnmanagedToString(categoryChars, categoryCharsLen); + var nativeError = IgniteUtils.Utf8UnmanagedToString(errorInfoChars, errorInfoCharsLen); + + Exception ex = null; + + if (memPtr != 0 && _ignite != null) + { + using (var stream = IgniteManager.Memory.Get(memPtr).GetStream()) + { + ex = _ignite.Marshaller.Unmarshal<Exception>(stream); + } + } + + _log.Log((LogLevel) level, message, null, CultureInfo.InvariantCulture, category, nativeError, ex); + }, true); + } + + private bool LoggerIsLevelEnabled(void* target, int level) + { + // When custom logger in .NET is not defined, Java should not call us. + Debug.Assert(!(_log is JavaLogger)); + + return SafeCall(() => _log.IsEnabled((LogLevel) level), true); + } + private static void ConsoleWrite(sbyte* chars, int charsLen, bool isErr) { try @@ -1246,6 +1296,8 @@ namespace Apache.Ignite.Core.Impl.Unmanaged } catch (Exception e) { + _log.Error(e, "Failure in Java callback"); + UU.ThrowToJava(_ctx.NativeContext, e); } } @@ -1262,6 +1314,8 @@ namespace Apache.Ignite.Core.Impl.Unmanaged } catch (Exception e) { + _log.Error(e, "Failure in Java callback"); + UU.ThrowToJava(_ctx.NativeContext, e); return default(T); @@ -1287,6 +1341,14 @@ namespace Apache.Ignite.Core.Impl.Unmanaged } /// <summary> + /// Gets the log. + /// </summary> + public ILogger Log + { + get { return _log; } + } + + /// <summary> /// Create function pointer for the given function. /// </summary> private void* CreateFunctionPointer(Delegate del) @@ -1323,6 +1385,8 @@ namespace Apache.Ignite.Core.Impl.Unmanaged } _initEvent.Set(); + + ResourceProcessor.Inject(_log, grid); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs index 0e9556d..f89caa8 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs @@ -77,11 +77,12 @@ namespace Apache.Ignite.Core.Impl.Unmanaged #region NATIVE METHODS: PROCESSOR internal static void IgnitionStart(UnmanagedContext ctx, string cfgPath, string gridName, - bool clientMode) + bool clientMode, bool userLogger) { using (var mem = IgniteManager.Memory.Allocate().GetStream()) { mem.WriteBool(clientMode); + mem.WriteBool(userLogger); sbyte* cfgPath0 = IgniteUtils.StringToUtf8Unmanaged(cfgPath); sbyte* gridName0 = IgniteUtils.StringToUtf8Unmanaged(gridName); @@ -377,6 +378,30 @@ namespace Apache.Ignite.Core.Impl.Unmanaged JNI.ProcessorGetCacheNames(target.Context, target.Target, memPtr); } + internal static bool ProcessorLoggerIsLevelEnabled(IUnmanagedTarget target, int level) + { + return JNI.ProcessorLoggerIsLevelEnabled(target.Context, target.Target, level); + } + + internal static void ProcessorLoggerLog(IUnmanagedTarget target, int level, string message, string category, + string errorInfo) + { + var message0 = IgniteUtils.StringToUtf8Unmanaged(message); + var category0 = IgniteUtils.StringToUtf8Unmanaged(category); + var errorInfo0 = IgniteUtils.StringToUtf8Unmanaged(errorInfo); + + try + { + JNI.ProcessorLoggerLog(target.Context, target.Target, level, message0, category0, errorInfo0); + } + finally + { + Marshal.FreeHGlobal(new IntPtr(message0)); + Marshal.FreeHGlobal(new IntPtr(category0)); + Marshal.FreeHGlobal(new IntPtr(errorInfo0)); + } + } + #endregion #region NATIVE METHODS: TARGET http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Log/CategoryLogger.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Log/CategoryLogger.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Log/CategoryLogger.cs new file mode 100644 index 0000000..2d7f876 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Log/CategoryLogger.cs @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 Apache.Ignite.Core.Log +{ + using System; + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Wrapping logger with a predefined category. + /// <para /> + /// When <see cref="Log"/> method is called, and <c>category</c> parameter is null, predefined category + /// will be used. + /// </summary> + public class CategoryLogger : ILogger + { + /** Wrapped logger. */ + private readonly ILogger _logger; + + /** Category to use. */ + private readonly string _category; + + /// <summary> + /// Initializes a new instance of the <see cref="CategoryLogger"/> class. + /// </summary> + /// <param name="logger">The logger to wrap.</param> + /// <param name="category">The category.</param> + public CategoryLogger(ILogger logger, string category) + { + IgniteArgumentCheck.NotNull(logger, "log"); + + // If logger is already a CategoryLogger, get underlying logger instead to avoid unnecessary nesting. + var catLogger = logger as CategoryLogger; + _logger = catLogger != null ? catLogger._logger : logger; + + _category = category; + } + + /// <summary> + /// Logs the specified message. + /// </summary> + /// <param name="level">The level.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments to format <paramref name="message" />. + /// Can be null (formatting will not occur).</param> + /// <param name="formatProvider">The format provider. Can be null if <paramref name="args" /> is null.</param> + /// <param name="category">The logging category name.</param> + /// <param name="nativeErrorInfo">The native error information.</param> + /// <param name="ex">The exception. Can be null.</param> + public void Log(LogLevel level, string message, object[] args, IFormatProvider formatProvider, string category, + string nativeErrorInfo, Exception ex) + { + _logger.Log(level, message, args, formatProvider, category ?? _category, nativeErrorInfo, ex); + } + + /// <summary> + /// Determines whether the specified log level is enabled. + /// </summary> + /// <param name="level">The level.</param> + /// <returns> + /// Value indicating whether the specified log level is enabled + /// </returns> + public bool IsEnabled(LogLevel level) + { + return _logger.IsEnabled(level); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Log/ILogger.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Log/ILogger.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Log/ILogger.cs new file mode 100644 index 0000000..a2f2f20 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Log/ILogger.cs @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 Apache.Ignite.Core.Log +{ + using System; + + /// <summary> + /// Defines Ignite logging interface. + /// <para /> + /// This interface only provides essential log methods. + /// All convenience overloads are in <see cref="LoggerExtensions"/>. + /// </summary> + public interface ILogger + { + /// <summary> + /// Logs the specified message. + /// </summary> + /// <param name="level">The level.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments to format <paramref name="message" />. + /// Can be null (formatting will not occur).</param> + /// <param name="formatProvider">The format provider. Can be null if <paramref name="args" /> is null.</param> + /// <param name="category">The logging category name.</param> + /// <param name="nativeErrorInfo">The native error information.</param> + /// <param name="ex">The exception. Can be null.</param> + void Log(LogLevel level, string message, object[] args, IFormatProvider formatProvider, string category, + string nativeErrorInfo, Exception ex); + + /// <summary> + /// Determines whether the specified log level is enabled. + /// </summary> + /// <param name="level">The level.</param> + /// <returns>Value indicating whether the specified log level is enabled</returns> + bool IsEnabled(LogLevel level); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Log/LogLevel.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Log/LogLevel.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Log/LogLevel.cs new file mode 100644 index 0000000..75694ab --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Log/LogLevel.cs @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 Apache.Ignite.Core.Log +{ + using System; + + /// <summary> + /// Defines log levels. + /// </summary> + [Serializable] + public enum LogLevel + { + /// <summary> + /// Trace log level. + /// </summary> + Trace = 0, + + /// <summary> + /// Debug log level. + /// </summary> + Debug = 1, + + /// <summary> + /// Info log level. + /// </summary> + Info = 2, + + /// <summary> + /// Warning log level. + /// </summary> + Warn = 3, + + /// <summary> + /// Error log level. + /// </summary> + Error = 4 + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/3c9e254e/modules/platforms/dotnet/Apache.Ignite.Core/Log/LoggerExtensions.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Log/LoggerExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Log/LoggerExtensions.cs new file mode 100644 index 0000000..93748e3 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Log/LoggerExtensions.cs @@ -0,0 +1,320 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 Apache.Ignite.Core.Log +{ + using System; + using System.Globalization; + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Extension methods for <see cref="ILogger" /> + /// </summary> + public static class LoggerExtensions + { + // 4 overloads per level (message, message+args, ex+message, ex+message+args) + + /// <summary> + /// Logs the message with <see cref="LogLevel.Trace"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + public static void Trace(this ILogger logger, string message) + { + Log(logger, LogLevel.Trace, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Trace"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Trace(this ILogger logger, string message, params object[] args) + { + Log(logger, LogLevel.Trace, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Trace"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + public static void Trace(this ILogger logger, Exception ex, string message) + { + Log(logger, LogLevel.Trace, ex, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Trace"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Trace(this ILogger logger, Exception ex, string message, params object[] args) + { + Log(logger, LogLevel.Trace, ex, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Debug"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + public static void Debug(this ILogger logger, string message) + { + Log(logger, LogLevel.Debug, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Debug"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Debug(this ILogger logger, string message, params object[] args) + { + Log(logger, LogLevel.Debug, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Debug"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + public static void Debug(this ILogger logger, Exception ex, string message) + { + Log(logger, LogLevel.Debug, ex, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Debug"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Debug(this ILogger logger, Exception ex, string message, params object[] args) + { + Log(logger, LogLevel.Debug, ex, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Info"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + public static void Info(this ILogger logger, string message) + { + Log(logger, LogLevel.Info, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Info"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Info(this ILogger logger, string message, params object[] args) + { + Log(logger, LogLevel.Info, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Info"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + public static void Info(this ILogger logger, Exception ex, string message) + { + Log(logger, LogLevel.Info, ex, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Info"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Info(this ILogger logger, Exception ex, string message, params object[] args) + { + Log(logger, LogLevel.Info, ex, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Warn"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + public static void Warn(this ILogger logger, string message) + { + Log(logger, LogLevel.Warn, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Warn"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Warn(this ILogger logger, string message, params object[] args) + { + Log(logger, LogLevel.Warn, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Warn"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + public static void Warn(this ILogger logger, Exception ex, string message) + { + Log(logger, LogLevel.Warn, ex, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Warn"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Warn(this ILogger logger, Exception ex, string message, params object[] args) + { + Log(logger, LogLevel.Warn, ex, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Error"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + public static void Error(this ILogger logger, string message) + { + Log(logger, LogLevel.Error, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Error"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Error(this ILogger logger, string message, params object[] args) + { + Log(logger, LogLevel.Error, message, args); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Error"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + public static void Error(this ILogger logger, Exception ex, string message) + { + Log(logger, LogLevel.Error, ex, message); + } + + /// <summary> + /// Logs the message with <see cref="LogLevel.Error"/> level. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Error(this ILogger logger, Exception ex, string message, params object[] args) + { + Log(logger, LogLevel.Error, ex, message, args); + } + + /// <summary> + /// Logs the message. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="level">The level.</param> + /// <param name="message">The message.</param> + public static void Log(this ILogger logger, LogLevel level, string message) + { + IgniteArgumentCheck.NotNull(logger, "logger"); + + logger.Log(level, message, null, null, null, null, null); + } + + /// <summary> + /// Logs the message. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="level">The level.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Log(this ILogger logger, LogLevel level, string message, params object[] args) + { + IgniteArgumentCheck.NotNull(logger, "logger"); + + logger.Log(level, message, args, CultureInfo.InvariantCulture, null, null, null); + } + + /// <summary> + /// Logs the message. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="level">The level.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + public static void Log(this ILogger logger, LogLevel level, Exception ex, string message) + { + IgniteArgumentCheck.NotNull(logger, "logger"); + + logger.Log(level, message, null, null, null, null, ex); + } + + /// <summary> + /// Logs the message. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="level">The level.</param> + /// <param name="ex">The exception.</param> + /// <param name="message">The message.</param> + /// <param name="args">The arguments.</param> + public static void Log(this ILogger logger, LogLevel level, Exception ex, string message, params object[] args) + { + IgniteArgumentCheck.NotNull(logger, "logger"); + + logger.Log(level, message, args, CultureInfo.InvariantCulture, null, null, ex); + } + + /// <summary> + /// Gets the <see cref="CategoryLogger"/> with a specified category that wraps provided logger. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="category">The category.</param> + /// <returns>Logger that always uses specified category.</returns> + public static ILogger GetLogger(this ILogger logger, string category) + { + IgniteArgumentCheck.NotNull(logger, "logger"); + + return new CategoryLogger(logger, category); + } + } +} \ No newline at end of file
