Commit 43005e3b authored by Lemon's avatar Lemon Committed by 吴晟 Wu Sheng

Add logging module to record internal events of agent. (#26)

* Refactor SkyWalking.Diagnostics module

* Init SkyWalking.Extensions.DependencyInjection project

* Add dependency package

* Refactor SkyWalking.AspNetCore

* Rename AddSkyWalkingCore to AddSkyWalking

* Add logging module to record internal events of agent.

* Fix SkyWalkingHostedService
parent f7c2cd6e
{ {
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "Debug": {
"Default": "Debug", "LogLevel": {
"System": "Information", "Default": "Debug"
"Microsoft": "Information" }
},
"Console": {
"LogLevel": {
"Default": "Debug"
}
} }
} }
} }
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
namespace SkyWalking.Logging
{
public interface ILogger
{
void Debug(string message);
void Info(string message);
void Warning(string message);
void Error(string message, Exception exception);
void Trace(string message);
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
namespace SkyWalking.Logging
{
public interface ILoggerFactory
{
ILogger CreateLogger(Type type);
}
}
\ No newline at end of file
...@@ -20,8 +20,10 @@ using Microsoft.Extensions.DependencyInjection; ...@@ -20,8 +20,10 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Http; using Microsoft.Extensions.Http;
using SkyWalking.AspNetCore.Diagnostics; using SkyWalking.AspNetCore.Diagnostics;
using SkyWalking.AspNetCore.Logging;
using SkyWalking.Diagnostics; using SkyWalking.Diagnostics;
using SkyWalking.Extensions.DependencyInjection; using SkyWalking.Extensions.DependencyInjection;
using SkyWalking.Logging;
namespace SkyWalking.AspNetCore namespace SkyWalking.AspNetCore
{ {
...@@ -31,6 +33,7 @@ namespace SkyWalking.AspNetCore ...@@ -31,6 +33,7 @@ namespace SkyWalking.AspNetCore
{ {
builder.Services.AddSingleton<IHostedService, SkyWalkingHostedService>(); builder.Services.AddSingleton<IHostedService, SkyWalkingHostedService>();
builder.Services.AddSingleton<ITracingDiagnosticProcessor, HostingDiagnosticProcessor>(); builder.Services.AddSingleton<ITracingDiagnosticProcessor, HostingDiagnosticProcessor>();
builder.Services.AddSingleton<ILoggerFactory, LoggerFactoryAdapter>();
return builder; return builder;
} }
......
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
using Microsoft.Extensions.Logging;
using ILogger = SkyWalking.Logging.ILogger;
using MSLogger = Microsoft.Extensions.Logging.ILogger;
namespace SkyWalking.AspNetCore.Logging
{
internal class LoggerAdapter : ILogger
{
private readonly MSLogger _logger;
public LoggerAdapter(MSLogger logger)
{
_logger = logger;
}
public void Debug(string message)
{
_logger.LogDebug(message);
}
public void Info(string message)
{
_logger.LogInformation(message);
}
public void Warning(string message)
{
_logger.LogWarning(message);
}
public void Error(string message, Exception exception)
{
_logger.LogError(exception, message);
}
public void Trace(string message)
{
_logger.LogTrace(message);
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
using MSLoggerFactory= Microsoft.Extensions.Logging.ILoggerFactory;
using Microsoft.Extensions.Logging;
using ILoggerFactory = SkyWalking.Logging.ILoggerFactory;
using ILogger = SkyWalking.Logging.ILogger;
namespace SkyWalking.AspNetCore.Logging
{
internal class LoggerFactoryAdapter : ILoggerFactory
{
private readonly MSLoggerFactory _loggerFactory;
public LoggerFactoryAdapter(MSLoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
}
public ILogger CreateLogger(Type type)
{
return new LoggerAdapter(_loggerFactory.CreateLogger(type));
}
}
}
\ No newline at end of file
...@@ -25,6 +25,7 @@ using Microsoft.Extensions.Options; ...@@ -25,6 +25,7 @@ using Microsoft.Extensions.Options;
using SkyWalking.Boot; using SkyWalking.Boot;
using SkyWalking.Config; using SkyWalking.Config;
using SkyWalking.Diagnostics; using SkyWalking.Diagnostics;
using SkyWalking.Logging;
using SkyWalking.Remote; using SkyWalking.Remote;
namespace SkyWalking.AspNetCore namespace SkyWalking.AspNetCore
...@@ -32,9 +33,12 @@ namespace SkyWalking.AspNetCore ...@@ -32,9 +33,12 @@ namespace SkyWalking.AspNetCore
public class SkyWalkingHostedService : IHostedService public class SkyWalkingHostedService : IHostedService
{ {
private readonly TracingDiagnosticObserver _diagnosticObserver; private readonly TracingDiagnosticObserver _diagnosticObserver;
private readonly ILogger _logger;
public SkyWalkingHostedService(IOptions<SkyWalkingOptions> options, IHostingEnvironment hostingEnvironment, TracingDiagnosticObserver diagnosticObserver)
public SkyWalkingHostedService(IOptions<SkyWalkingOptions> options, IHostingEnvironment hostingEnvironment,
TracingDiagnosticObserver diagnosticObserver, ILoggerFactory loggerFactory)
{ {
if (string.IsNullOrEmpty(options.Value.DirectServers)) if (string.IsNullOrEmpty(options.Value.DirectServers))
{ {
throw new ArgumentException("DirectServers cannot be empty or null."); throw new ArgumentException("DirectServers cannot be empty or null.");
...@@ -45,22 +49,43 @@ namespace SkyWalking.AspNetCore ...@@ -45,22 +49,43 @@ namespace SkyWalking.AspNetCore
options.Value.ApplicationCode = hostingEnvironment.ApplicationName; options.Value.ApplicationCode = hostingEnvironment.ApplicationName;
} }
LogManager.SetLoggerFactory(loggerFactory);
AgentConfig.ApplicationCode = options.Value.ApplicationCode; AgentConfig.ApplicationCode = options.Value.ApplicationCode;
CollectorConfig.DirectServers = options.Value.DirectServers; CollectorConfig.DirectServers = options.Value.DirectServers;
_logger = LogManager.GetLogger<SkyWalkingHostedService>();
_diagnosticObserver = diagnosticObserver; _diagnosticObserver = diagnosticObserver;
} }
public async Task StartAsync(CancellationToken cancellationToken) public async Task StartAsync(CancellationToken cancellationToken)
{ {
await GrpcChannelManager.Instance.ConnectAsync(); _logger.Info("SkyWalking Agent starting...");
await ServiceManager.Instance.Initialize(); try
DiagnosticListener.AllListeners.Subscribe(_diagnosticObserver); {
await GrpcChannelManager.Instance.ConnectAsync();
await ServiceManager.Instance.Initialize();
DiagnosticListener.AllListeners.Subscribe(_diagnosticObserver);
_logger.Info("SkyWalking Agent started.");
}
catch (Exception e)
{
_logger.Error("SkyWalking Agent start fail.", e);
}
} }
public async Task StopAsync(CancellationToken cancellationToken) public async Task StopAsync(CancellationToken cancellationToken)
{ {
await GrpcChannelManager.Instance.ShutdownAsync(); _logger.Info("SkyWalking Agent stopping...");
ServiceManager.Instance.Dispose(); try
{
await GrpcChannelManager.Instance.ShutdownAsync();
ServiceManager.Instance.Dispose();
_logger.Info("SkyWalking Agent stopped.");
}
catch (Exception e)
{
_logger.Error("SkyWalking Agent stop fail.", e);
}
} }
} }
} }
\ No newline at end of file
...@@ -22,11 +22,13 @@ using System.Linq; ...@@ -22,11 +22,13 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Logging;
namespace SkyWalking.Boot namespace SkyWalking.Boot
{ {
public class ServiceManager : IDisposable public class ServiceManager : IDisposable
{ {
private static readonly ILogger _logger = LogManager.GetLogger<ServiceManager>();
private static readonly ServiceManager _instance = new ServiceManager(); private static readonly ServiceManager _instance = new ServiceManager();
public static ServiceManager Instance => _instance; public static ServiceManager Instance => _instance;
...@@ -59,10 +61,19 @@ namespace SkyWalking.Boot ...@@ -59,10 +61,19 @@ namespace SkyWalking.Boot
public async Task Initialize() public async Task Initialize()
{ {
var types = FindServiceTypes(); var types = FindServiceTypes();
foreach (var service in types.Select(Activator.CreateInstance).OfType<IBootService>().OrderBy(x => x.Order)) foreach (var service in types.Select(Activator.CreateInstance).OfType<IBootService>().OrderBy(x => x.Order))
{ {
await service.Initialize(_tokenSource.Token); try
_services.Add(service.GetType(), service); {
await service.Initialize(_tokenSource.Token);
_services.Add(service.GetType(), service);
_logger.Debug($"ServiceManager init {service.GetType()}.");
}
catch (Exception e)
{
_logger.Error($"ServiceManager init {service.GetType()} fail.",e);
}
} }
} }
...@@ -72,8 +83,16 @@ namespace SkyWalking.Boot ...@@ -72,8 +83,16 @@ namespace SkyWalking.Boot
_tokenSource.Cancel(); _tokenSource.Cancel();
foreach (var item in _services.Values) foreach (var item in _services.Values)
{ {
var service = item as IBootService; try
service?.Dispose(); {
var service = item as IBootService;
service?.Dispose();
_logger.Debug($"ServiceManager dispose {item.GetType()}.");
}
catch (Exception e)
{
_logger.Error($"ServiceManager dispose {item.GetType()} fail.", e);
}
} }
_tokenSource.Dispose(); _tokenSource.Dispose();
} }
......
...@@ -19,11 +19,13 @@ ...@@ -19,11 +19,13 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Logging;
namespace SkyWalking.Boot namespace SkyWalking.Boot
{ {
public abstract class TimerService : IBootService public abstract class TimerService : IBootService
{ {
private static readonly ILogger _logger = LogManager.GetLogger<TimerService>();
protected abstract TimeSpan Interval { get; } protected abstract TimeSpan Interval { get; }
private Task _task; private Task _task;
...@@ -40,7 +42,14 @@ namespace SkyWalking.Boot ...@@ -40,7 +42,14 @@ namespace SkyWalking.Boot
{ {
while (true) while (true)
{ {
await Execute(token); try
{
await Execute(token);
}
catch (Exception e)
{
_logger.Error($"{GetType().Name} execute fail.", e);
}
await Task.Delay(Interval, token); await Task.Delay(Interval, token);
} }
}, },
......
...@@ -19,12 +19,15 @@ ...@@ -19,12 +19,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using SkyWalking.Logging;
using SkyWalking.Utils; using SkyWalking.Utils;
namespace SkyWalking.Diagnostics namespace SkyWalking.Diagnostics
{ {
public abstract class TracingDiagnosticObserver : IObserver<DiagnosticListener> public abstract class TracingDiagnosticObserver : IObserver<DiagnosticListener>
{ {
private static readonly ILogger _logger = LogManager.GetLogger<TracingDiagnosticObserver>();
private readonly IEnumerable<ITracingDiagnosticProcessor> _tracingDiagnosticProcessors; private readonly IEnumerable<ITracingDiagnosticProcessor> _tracingDiagnosticProcessors;
public TracingDiagnosticObserver(IEnumerable<ITracingDiagnosticProcessor> tracingDiagnosticProcessors) public TracingDiagnosticObserver(IEnumerable<ITracingDiagnosticProcessor> tracingDiagnosticProcessors)
...@@ -48,6 +51,7 @@ namespace SkyWalking.Diagnostics ...@@ -48,6 +51,7 @@ namespace SkyWalking.Diagnostics
if (listener.Name == diagnosticProcessor.ListenerName) if (listener.Name == diagnosticProcessor.ListenerName)
{ {
OnNext(listener, diagnosticProcessor); OnNext(listener, diagnosticProcessor);
_logger.Debug($"TracingDiagnosticObserver -- Subscribe {diagnosticProcessor.ListenerName}.");
} }
} }
} }
......
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
namespace SkyWalking.Logging
{
public static class LogManager
{
private static readonly ILoggerFactory defaultLoggerFactory = new NullLoggerFactory();
private static ILoggerFactory _loggerFactory;
public static ILogger GetLogger(Type type)
{
var loggerFactory = _loggerFactory ?? defaultLoggerFactory;
return loggerFactory.CreateLogger(type);
}
public static ILogger GetLogger<T>()
{
return GetLogger(typeof(T));
}
public static void SetLoggerFactory(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
namespace SkyWalking.Logging
{
internal class NullLogger : ILogger
{
public void Debug(string message)
{
}
public void Info(string message)
{
}
public void Warning(string message)
{
}
public void Error(string message, Exception exception)
{
}
public void Trace(string message)
{
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking 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.
*
*/
using System;
namespace SkyWalking.Logging
{
internal class NullLoggerFactory : ILoggerFactory
{
public ILogger CreateLogger(Type type)
{
return null;
}
}
}
\ No newline at end of file
...@@ -16,17 +16,21 @@ ...@@ -16,17 +16,21 @@
* *
*/ */
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Boot; using SkyWalking.Boot;
using SkyWalking.Context; using SkyWalking.Context;
using SkyWalking.Context.Trace; using SkyWalking.Context.Trace;
using SkyWalking.Logging;
using SkyWalking.NetworkProtocol; using SkyWalking.NetworkProtocol;
namespace SkyWalking.Remote namespace SkyWalking.Remote
{ {
public class GrpcTraceSegmentService : IBootService, ITracingContextListener public class GrpcTraceSegmentService : IBootService, ITracingContextListener
{ {
private static readonly ILogger _logger = LogManager.GetLogger<GrpcTraceSegmentService>();
public void Dispose() public void Dispose()
{ {
TracingContext.ListenerManager.Remove(this); TracingContext.ListenerManager.Remove(this);
...@@ -42,14 +46,26 @@ namespace SkyWalking.Remote ...@@ -42,14 +46,26 @@ namespace SkyWalking.Remote
public async void AfterFinished(ITraceSegment traceSegment) public async void AfterFinished(ITraceSegment traceSegment)
{ {
var segment = traceSegment.Transform(); if (traceSegment.IsIgnore)
var traceSegmentService =
new TraceSegmentService.TraceSegmentServiceClient(GrpcChannelManager.Instance.Channel);
using (var asyncClientStreamingCall = traceSegmentService.collect())
{ {
await asyncClientStreamingCall.RequestStream.WriteAsync(segment); return;
await asyncClientStreamingCall.RequestStream.CompleteAsync();
} }
try
{
var segment = traceSegment.Transform();
var traceSegmentService =
new TraceSegmentService.TraceSegmentServiceClient(GrpcChannelManager.Instance.Channel);
using (var asyncClientStreamingCall = traceSegmentService.collect())
{
await asyncClientStreamingCall.RequestStream.WriteAsync(segment);
await asyncClientStreamingCall.RequestStream.CompleteAsync();
}
}
catch (Exception e)
{
_logger.Error("Transform and send UpstreamSegment to collector fail.", e);
}
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment