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": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
"Debug": {
"LogLevel": {
"Default": "Debug"
}
},
"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;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Http;
using SkyWalking.AspNetCore.Diagnostics;
using SkyWalking.AspNetCore.Logging;
using SkyWalking.Diagnostics;
using SkyWalking.Extensions.DependencyInjection;
using SkyWalking.Logging;
namespace SkyWalking.AspNetCore
{
......@@ -31,6 +33,7 @@ namespace SkyWalking.AspNetCore
{
builder.Services.AddSingleton<IHostedService, SkyWalkingHostedService>();
builder.Services.AddSingleton<ITracingDiagnosticProcessor, HostingDiagnosticProcessor>();
builder.Services.AddSingleton<ILoggerFactory, LoggerFactoryAdapter>();
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;
using SkyWalking.Boot;
using SkyWalking.Config;
using SkyWalking.Diagnostics;
using SkyWalking.Logging;
using SkyWalking.Remote;
namespace SkyWalking.AspNetCore
......@@ -32,9 +33,12 @@ namespace SkyWalking.AspNetCore
public class SkyWalkingHostedService : IHostedService
{
private readonly TracingDiagnosticObserver _diagnosticObserver;
public SkyWalkingHostedService(IOptions<SkyWalkingOptions> options, IHostingEnvironment hostingEnvironment, TracingDiagnosticObserver diagnosticObserver)
private readonly ILogger _logger;
public SkyWalkingHostedService(IOptions<SkyWalkingOptions> options, IHostingEnvironment hostingEnvironment,
TracingDiagnosticObserver diagnosticObserver, ILoggerFactory loggerFactory)
{
if (string.IsNullOrEmpty(options.Value.DirectServers))
{
throw new ArgumentException("DirectServers cannot be empty or null.");
......@@ -45,22 +49,43 @@ namespace SkyWalking.AspNetCore
options.Value.ApplicationCode = hostingEnvironment.ApplicationName;
}
LogManager.SetLoggerFactory(loggerFactory);
AgentConfig.ApplicationCode = options.Value.ApplicationCode;
CollectorConfig.DirectServers = options.Value.DirectServers;
_logger = LogManager.GetLogger<SkyWalkingHostedService>();
_diagnosticObserver = diagnosticObserver;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
await GrpcChannelManager.Instance.ConnectAsync();
await ServiceManager.Instance.Initialize();
DiagnosticListener.AllListeners.Subscribe(_diagnosticObserver);
_logger.Info("SkyWalking Agent starting...");
try
{
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)
{
await GrpcChannelManager.Instance.ShutdownAsync();
ServiceManager.Instance.Dispose();
_logger.Info("SkyWalking Agent stopping...");
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;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using SkyWalking.Logging;
namespace SkyWalking.Boot
{
public class ServiceManager : IDisposable
{
private static readonly ILogger _logger = LogManager.GetLogger<ServiceManager>();
private static readonly ServiceManager _instance = new ServiceManager();
public static ServiceManager Instance => _instance;
......@@ -59,10 +61,19 @@ namespace SkyWalking.Boot
public async Task Initialize()
{
var types = FindServiceTypes();
foreach (var service in types.Select(Activator.CreateInstance).OfType<IBootService>().OrderBy(x => x.Order))
{
await service.Initialize(_tokenSource.Token);
_services.Add(service.GetType(), service);
try
{
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
_tokenSource.Cancel();
foreach (var item in _services.Values)
{
var service = item as IBootService;
service?.Dispose();
try
{
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();
}
......
......@@ -19,11 +19,13 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using SkyWalking.Logging;
namespace SkyWalking.Boot
{
public abstract class TimerService : IBootService
{
private static readonly ILogger _logger = LogManager.GetLogger<TimerService>();
protected abstract TimeSpan Interval { get; }
private Task _task;
......@@ -40,7 +42,14 @@ namespace SkyWalking.Boot
{
while (true)
{
await Execute(token);
try
{
await Execute(token);
}
catch (Exception e)
{
_logger.Error($"{GetType().Name} execute fail.", e);
}
await Task.Delay(Interval, token);
}
},
......
......@@ -19,12 +19,15 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using SkyWalking.Logging;
using SkyWalking.Utils;
namespace SkyWalking.Diagnostics
{
public abstract class TracingDiagnosticObserver : IObserver<DiagnosticListener>
{
private static readonly ILogger _logger = LogManager.GetLogger<TracingDiagnosticObserver>();
private readonly IEnumerable<ITracingDiagnosticProcessor> _tracingDiagnosticProcessors;
public TracingDiagnosticObserver(IEnumerable<ITracingDiagnosticProcessor> tracingDiagnosticProcessors)
......@@ -48,6 +51,7 @@ namespace SkyWalking.Diagnostics
if (listener.Name == diagnosticProcessor.ListenerName)
{
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 @@
*
*/
using System;
using System.Threading;
using System.Threading.Tasks;
using SkyWalking.Boot;
using SkyWalking.Context;
using SkyWalking.Context.Trace;
using SkyWalking.Logging;
using SkyWalking.NetworkProtocol;
namespace SkyWalking.Remote
{
public class GrpcTraceSegmentService : IBootService, ITracingContextListener
{
private static readonly ILogger _logger = LogManager.GetLogger<GrpcTraceSegmentService>();
public void Dispose()
{
TracingContext.ListenerManager.Remove(this);
......@@ -42,14 +46,26 @@ namespace SkyWalking.Remote
public async void AfterFinished(ITraceSegment traceSegment)
{
var segment = traceSegment.Transform();
var traceSegmentService =
new TraceSegmentService.TraceSegmentServiceClient(GrpcChannelManager.Instance.Channel);
using (var asyncClientStreamingCall = traceSegmentService.collect())
if (traceSegment.IsIgnore)
{
await asyncClientStreamingCall.RequestStream.WriteAsync(segment);
await asyncClientStreamingCall.RequestStream.CompleteAsync();
return;
}
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