Browse Source

Added system info and background task start/stop to logs

tags/1.0-rc
RogueException 9 years ago
parent
commit
d667420303
4 changed files with 93 additions and 16 deletions
  1. +33
    -3
      src/Discord.Net/DiscordClient.cs
  2. +12
    -5
      src/Discord.Net/DiscordSocketClient.cs
  3. +47
    -8
      src/Discord.Net/Logging/LogMessage.cs
  4. +1
    -0
      src/Discord.Net/project.json

+ 33
- 3
src/Discord.Net/DiscordClient.cs View File

@@ -9,6 +9,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Runtime.InteropServices;


namespace Discord namespace Discord
{ {
@@ -24,11 +25,12 @@ namespace Discord
public event Func<Task> LoggedOut { add { _loggedOutEvent.Add(value); } remove { _loggedOutEvent.Remove(value); } } public event Func<Task> LoggedOut { add { _loggedOutEvent.Add(value); } remove { _loggedOutEvent.Remove(value); } }
private readonly AsyncEvent<Func<Task>> _loggedOutEvent = new AsyncEvent<Func<Task>>(); private readonly AsyncEvent<Func<Task>> _loggedOutEvent = new AsyncEvent<Func<Task>>();


internal readonly ILogger _discordLogger, _restLogger, _queueLogger;
internal readonly ILogger _clientLogger, _restLogger, _queueLogger;
internal readonly SemaphoreSlim _connectionLock; internal readonly SemaphoreSlim _connectionLock;
internal readonly RequestQueue _requestQueue; internal readonly RequestQueue _requestQueue;
internal bool _isDisposed; internal bool _isDisposed;
internal SelfUser _currentUser; internal SelfUser _currentUser;
private bool _isFirstLogSub;


public API.DiscordApiClient ApiClient { get; } public API.DiscordApiClient ApiClient { get; }
internal LogManager LogManager { get; } internal LogManager LogManager { get; }
@@ -41,9 +43,10 @@ namespace Discord
{ {
LogManager = new LogManager(config.LogLevel); LogManager = new LogManager(config.LogLevel);
LogManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false); LogManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false);
_discordLogger = LogManager.CreateLogger("Discord");
_clientLogger = LogManager.CreateLogger("Client");
_restLogger = LogManager.CreateLogger("Rest"); _restLogger = LogManager.CreateLogger("Rest");
_queueLogger = LogManager.CreateLogger("Queue"); _queueLogger = LogManager.CreateLogger("Queue");
_isFirstLogSub = true;


_connectionLock = new SemaphoreSlim(1, 1); _connectionLock = new SemaphoreSlim(1, 1);


@@ -73,6 +76,12 @@ namespace Discord
} }
private async Task LoginInternalAsync(TokenType tokenType, string token, bool validateToken) private async Task LoginInternalAsync(TokenType tokenType, string token, bool validateToken)
{ {
if (_isFirstLogSub)
{
_isFirstLogSub = false;
await WriteInitialLog().ConfigureAwait(false);
}

if (LoginState != LoginState.LoggedOut) if (LoginState != LoginState.LoggedOut)
await LogoutInternalAsync().ConfigureAwait(false); await LogoutInternalAsync().ConfigureAwait(false);
LoginState = LoginState.LoggingIn; LoginState = LoginState.LoggingIn;
@@ -276,7 +285,28 @@ namespace Discord
} }
/// <inheritdoc /> /// <inheritdoc />
public void Dispose() => Dispose(true); public void Dispose() => Dispose(true);

protected async Task WriteInitialLog()
{
if (this is DiscordSocketClient)
await _clientLogger.InfoAsync($"DiscordSocketClient v{DiscordConfig.Version} (Gateway v{DiscordConfig.GatewayAPIVersion}, {DiscordConfig.GatewayEncoding})").ConfigureAwait(false);
else
await _clientLogger.InfoAsync($"DiscordClient v{DiscordConfig.Version}").ConfigureAwait(false);
await _clientLogger.VerboseAsync($"Runtime: {RuntimeInformation.FrameworkDescription.Trim()} ({ToArchString(RuntimeInformation.ProcessArchitecture)})").ConfigureAwait(false);
await _clientLogger.VerboseAsync($"OS: {RuntimeInformation.OSDescription.Trim()} ({ToArchString(RuntimeInformation.OSArchitecture)})").ConfigureAwait(false);
await _clientLogger.VerboseAsync($"Processors: {Environment.ProcessorCount}").ConfigureAwait(false);
}

private static string ToArchString(Architecture arch)
{
switch (arch)
{
case Architecture.X64: return "x64";
case Architecture.X86: return "x86";
default: return arch.ToString();
}
}

ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected; ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected;
ILogManager IDiscordClient.LogManager => LogManager; ILogManager IDiscordClient.LogManager => LogManager;




+ 12
- 5
src/Discord.Net/DiscordSocketClient.cs View File

@@ -450,7 +450,7 @@ namespace Discord
var data = (payload as JToken).ToObject<HelloEvent>(_serializer); var data = (payload as JToken).ToObject<HelloEvent>(_serializer);


_heartbeatTime = 0; _heartbeatTime = 0;
_heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _cancelToken.Token);
_heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _cancelToken.Token, _clientLogger);
} }
break; break;
case GatewayOpCode.Heartbeat: case GatewayOpCode.Heartbeat:
@@ -526,7 +526,7 @@ namespace Discord
_lastGuildAvailableTime = Environment.TickCount; _lastGuildAvailableTime = Environment.TickCount;
DataStore = dataStore; DataStore = dataStore;


_guildDownloadTask = WaitForGuildsAsync(_cancelToken.Token);
_guildDownloadTask = WaitForGuildsAsync(_cancelToken.Token, _clientLogger);


await _readyEvent.InvokeAsync().ConfigureAwait(false); await _readyEvent.InvokeAsync().ConfigureAwait(false);
await SyncGuildsAsync().ConfigureAwait(false); await SyncGuildsAsync().ConfigureAwait(false);
@@ -1231,11 +1231,12 @@ namespace Discord
#endif #endif
} }


private async Task RunHeartbeatAsync(int intervalMillis, CancellationToken cancelToken)
private async Task RunHeartbeatAsync(int intervalMillis, CancellationToken cancelToken, ILogger logger)
{ {
//Clean this up when Discord's session patch is live //Clean this up when Discord's session patch is live
try try
{ {
await logger.DebugAsync("Heartbeat Started").ConfigureAwait(false);
while (!cancelToken.IsCancellationRequested) while (!cancelToken.IsCancellationRequested)
{ {
await Task.Delay(intervalMillis, cancelToken).ConfigureAwait(false); await Task.Delay(intervalMillis, cancelToken).ConfigureAwait(false);
@@ -1253,13 +1254,19 @@ namespace Discord
_heartbeatTime = Environment.TickCount; _heartbeatTime = Environment.TickCount;
await ApiClient.SendHeartbeatAsync(_lastSeq).ConfigureAwait(false); await ApiClient.SendHeartbeatAsync(_lastSeq).ConfigureAwait(false);
} }
await logger.DebugAsync("Heartbeat Stopped").ConfigureAwait(false);
}
catch (OperationCanceledException ex)
{
await logger.DebugAsync("Heartbeat Stopped", ex).ConfigureAwait(false);
} }
catch (OperationCanceledException) { }
} }
private async Task WaitForGuildsAsync(CancellationToken cancelToken)
private async Task WaitForGuildsAsync(CancellationToken cancelToken, ILogger logger)
{ {
await logger.DebugAsync("GuildDownloader Started").ConfigureAwait(false);
while ((_unavailableGuilds != 0) && (Environment.TickCount - _lastGuildAvailableTime < 2000)) while ((_unavailableGuilds != 0) && (Environment.TickCount - _lastGuildAvailableTime < 2000))
await Task.Delay(500, cancelToken).ConfigureAwait(false); await Task.Delay(500, cancelToken).ConfigureAwait(false);
await logger.DebugAsync("GuildDownloader Stopped").ConfigureAwait(false);
} }
private async Task SyncGuildsAsync() private async Task SyncGuildsAsync()
{ {


+ 47
- 8
src/Discord.Net/Logging/LogMessage.cs View File

@@ -20,26 +20,64 @@ namespace Discord


public override string ToString() => ToString(null, true); public override string ToString() => ToString(null, true);


public string ToString(StringBuilder builder = null, bool fullException = true)
public string ToString(StringBuilder builder = null, bool fullException = true, bool prependTimestamp = true, bool clearBuilder = true, DateTimeKind timestampKind = DateTimeKind.Local, int? padSource = 7)
{ {
string sourceName = Source; string sourceName = Source;
string message = Message; string message = Message;
string exMessage = fullException ? Exception?.ToString() : Exception?.Message; string exMessage = fullException ? Exception?.ToString() : Exception?.Message;


int maxLength = 1 + (sourceName?.Length ?? 0) + 2 + (message?.Length ?? 0) + 3 + (exMessage?.Length ?? 0);
int maxLength = 1 +
(prependTimestamp ? 8 : 0) + 1 +
(padSource.HasValue ? padSource.Value : sourceName?.Length ?? 0) + 1 +
(message?.Length ?? 0) +
(exMessage?.Length ?? 0) + 3;

if (builder == null) if (builder == null)
builder = new StringBuilder(maxLength); builder = new StringBuilder(maxLength);
else else
{ {
builder.Clear();
builder.EnsureCapacity(maxLength);
if (clearBuilder)
{
builder.Clear();
builder.EnsureCapacity(maxLength);
}
} }


if (prependTimestamp)
{
DateTime now;
if (timestampKind == DateTimeKind.Utc)
now = DateTime.UtcNow;
else
now = DateTime.Now;
if (now.Hour < 10)
builder.Append('0');
builder.Append(now.Hour);
builder.Append(':');
if (now.Minute < 10)
builder.Append('0');
builder.Append(now.Minute);
builder.Append(':');
if (now.Second < 10)
builder.Append('0');
builder.Append(now.Second);
builder.Append(' ');
}
if (sourceName != null) if (sourceName != null)
{ {
builder.Append('[');
builder.Append(sourceName);
builder.Append("] ");
if (padSource.HasValue)
{
if (sourceName.Length < padSource.Value)
{
builder.Append(sourceName);
builder.Append(' ', padSource.Value - sourceName.Length);
}
else if (sourceName.Length > padSource.Value)
builder.Append(sourceName.Substring(0, padSource.Value));
else
builder.Append(sourceName);
}
builder.Append(' ');
} }
if (!string.IsNullOrEmpty(Message)) if (!string.IsNullOrEmpty(Message))
{ {
@@ -53,7 +91,8 @@ namespace Discord
} }
if (exMessage != null) if (exMessage != null)
{ {
builder.AppendLine(":");
builder.Append(':');
builder.AppendLine();
builder.Append(exMessage); builder.Append(exMessage);
} }




+ 1
- 0
src/Discord.Net/project.json View File

@@ -31,6 +31,7 @@
"System.Net.WebSockets.Client": "4.0.0", "System.Net.WebSockets.Client": "4.0.0",
"System.Reflection.Extensions": "4.0.1", "System.Reflection.Extensions": "4.0.1",
"System.Runtime.InteropServices": "4.1.0", "System.Runtime.InteropServices": "4.1.0",
"System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
"System.Runtime.Serialization.Primitives": "4.1.1", "System.Runtime.Serialization.Primitives": "4.1.1",
"System.Text.RegularExpressions": "4.1.0" "System.Text.RegularExpressions": "4.1.0"
}, },


Loading…
Cancel
Save