Logging updates.

Fix log entry.

Additional logging.  Add environment badge.

Add logging.

Updater tweaks.

Add logging.

Updater changes.
This commit is contained in:
Jared Goodwin 2020-04-28 22:01:49 -07:00
parent a4e17d19c5
commit 3bcb4d2ede
32 changed files with 163 additions and 162 deletions

View File

@ -15,7 +15,7 @@ namespace Remotely.Agent.Installer.Win.Services
#if DEBUG
CheckLogFileExists();
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[DEBUG]\t{message}{Environment.NewLine}");
File.AppendAllText(LogPath, $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff}\t[Debug]\t{message}{Environment.NewLine}");
#endif
System.Diagnostics.Debug.WriteLine(message);
@ -30,7 +30,7 @@ namespace Remotely.Agent.Installer.Win.Services
lock (WriteLock)
{
CheckLogFileExists();
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[INFO]\t{message}{Environment.NewLine}");
File.AppendAllText(LogPath, $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff}\t[Info]\t{message}{Environment.NewLine}");
Console.WriteLine(message);
}
}
@ -49,7 +49,7 @@ namespace Remotely.Agent.Installer.Win.Services
while (exception != null)
{
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[ERROR]\t{exception?.Message}\t{exception?.StackTrace}\t{exception?.Source}{Environment.NewLine}");
File.AppendAllText(LogPath, $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff}\t[Error]\t{exception?.Message}\t{exception?.StackTrace}\t{exception?.Source}{Environment.NewLine}");
Console.WriteLine(exception.Message);
exception = exception.InnerException;
}

View File

@ -46,7 +46,6 @@ namespace Remotely.Agent
serviceCollection.AddTransient<PSCore>();
serviceCollection.AddTransient<WindowsPS>();
serviceCollection.AddScoped<ConfigService>();
serviceCollection.AddScoped<Logger>();
serviceCollection.AddSingleton<Updater>();
serviceCollection.AddScoped<Uninstaller>();
serviceCollection.AddScoped<ScriptRunner>();

View File

@ -13,6 +13,8 @@ using Remotely.Shared.Win32;
using Microsoft.Extensions.DependencyInjection;
using System.Text.Json;
using System.Threading;
using Remotely.Shared.Utilities;
using Remotely.Shared.Enums;
namespace Remotely.Agent.Services
{
@ -45,52 +47,67 @@ namespace Remotely.Agent.Services
private Uninstaller Uninstaller { get; }
public async Task Connect()
{
ConnectionInfo = ConfigService.GetConnectionInfo();
HubConnection = new HubConnectionBuilder()
.WithUrl(ConnectionInfo.Host + "/DeviceHub")
.Build();
RegisterMessageHandlers();
await HubConnection.StartAsync();
var device = await DeviceInformation.Create(ConnectionInfo.DeviceID, ConnectionInfo.OrganizationID);
var result = await HubConnection.InvokeAsync<bool>("DeviceCameOnline", device);
if (!result)
try
{
// Orgnanization ID wasn't found, or this device is already connected.
// The above can be caused by temporary issues on the server. So we'll do
// nothing here and wait for it to get resolved.
Logger.Write("There was an issue registering with the server. The server might be undergoing maintenance, or the supplied organization ID might be incorrect.");
await Task.Delay(TimeSpan.FromMinutes(1));
await HubConnection.StopAsync();
ConnectionInfo = ConfigService.GetConnectionInfo();
HubConnection = new HubConnectionBuilder()
.WithUrl(ConnectionInfo.Host + "/DeviceHub")
.Build();
RegisterMessageHandlers();
await HubConnection.StartAsync();
}
catch (Exception ex)
{
Logger.Write(ex, "Failed to connect to server. Internet connection may be unavailable.", EventType.Warning);
return;
}
if (string.IsNullOrWhiteSpace(ConnectionInfo.ServerVerificationToken))
try
{
IsServerVerified = true;
ConnectionInfo.ServerVerificationToken = Guid.NewGuid().ToString();
await HubConnection.SendAsync("SetServerVerificationToken", ConnectionInfo.ServerVerificationToken);
ConfigService.SaveConnectionInfo(ConnectionInfo);
}
else
{
await HubConnection.SendAsync("SendServerVerificationToken");
}
var device = await DeviceInformation.Create(ConnectionInfo.DeviceID, ConnectionInfo.OrganizationID);
if (ConfigService.TryGetDeviceSetupOptions(out DeviceSetupOptions options))
{
await HubConnection.SendAsync("DeviceSetupOptions", options, ConnectionInfo.DeviceID);
}
var result = await HubConnection.InvokeAsync<bool>("DeviceCameOnline", device);
HeartbeatTimer?.Dispose();
HeartbeatTimer = new System.Timers.Timer(TimeSpan.FromMinutes(5).TotalMilliseconds);
HeartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
HeartbeatTimer.Start();
if (!result)
{
// Orgnanization ID wasn't found, or this device is already connected.
// The above can be caused by temporary issues on the server. So we'll do
// nothing here and wait for it to get resolved.
Logger.Write("There was an issue registering with the server. The server might be undergoing maintenance, or the supplied organization ID might be incorrect.");
await Task.Delay(TimeSpan.FromMinutes(1));
await HubConnection.StopAsync();
return;
}
if (string.IsNullOrWhiteSpace(ConnectionInfo.ServerVerificationToken))
{
IsServerVerified = true;
ConnectionInfo.ServerVerificationToken = Guid.NewGuid().ToString();
await HubConnection.SendAsync("SetServerVerificationToken", ConnectionInfo.ServerVerificationToken);
ConfigService.SaveConnectionInfo(ConnectionInfo);
}
else
{
await HubConnection.SendAsync("SendServerVerificationToken");
}
if (ConfigService.TryGetDeviceSetupOptions(out DeviceSetupOptions options))
{
await HubConnection.SendAsync("DeviceSetupOptions", options, ConnectionInfo.DeviceID);
}
HeartbeatTimer?.Dispose();
HeartbeatTimer = new System.Timers.Timer(TimeSpan.FromMinutes(5).TotalMilliseconds);
HeartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
HeartbeatTimer.Start();
}
catch (Exception ex)
{
Logger.Write(ex, "Error starting websocket connection.", EventType.Error);
}
}
public async Task HandleConnection()

View File

@ -1,85 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace Remotely.Agent.Services
{
public class Logger
{
private static string LogPath => Path.Combine(Path.GetTempPath(), "Remotely_Logs.log");
private static object WriteLock { get; } = new object();
public static void Debug(string message)
{
lock (WriteLock)
{
#if DEBUG
CheckLogFileExists();
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[DEBUG]\t{message}{Environment.NewLine}");
#endif
System.Diagnostics.Debug.WriteLine(message);
}
}
public static void Write(string message)
{
try
{
lock (WriteLock)
{
CheckLogFileExists();
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[INFO]\t{message}{Environment.NewLine}");
Console.WriteLine(message);
}
}
catch { }
}
public static void Write(Exception ex)
{
lock (WriteLock)
{
try
{
CheckLogFileExists();
var exception = ex;
while (exception != null)
{
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[ERROR]\t{exception?.Message}\t{exception?.StackTrace}\t{exception?.Source}{Environment.NewLine}");
Console.WriteLine(exception.Message);
exception = exception.InnerException;
}
}
catch { }
}
}
private static void CheckLogFileExists()
{
if (!File.Exists(LogPath))
{
File.Create(LogPath).Close();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Process.Start("sudo", $"chmod 666 {LogPath}").WaitForExit();
}
}
if (File.Exists(LogPath))
{
var fi = new FileInfo(LogPath);
while (fi.Length > 1000000)
{
var content = File.ReadAllLines(LogPath);
File.WriteAllLines(LogPath, content.Skip(10));
fi = new FileInfo(LogPath);
}
}
}
}
}

View File

@ -86,8 +86,6 @@ namespace Remotely.Agent.Services
Logger.Write("Service Updater: Version is current.");
return;
}
File.WriteAllText("etag.txt", response.Headers["ETag"]);
}
catch (WebException ex) when ((ex.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotModified)
{
@ -137,7 +135,7 @@ namespace Remotely.Agent.Services
serverUrl + $"/api/AgentUpdate/DownloadPackage/win-{platform}/{downloadId}",
zipPath);
WebRequest.CreateHttp(serverUrl + $"/api/AgentUpdate/ClearDownload/{downloadId}").GetResponse();
await WebRequest.CreateHttp(serverUrl + $"/api/AgentUpdate/ClearDownload/{downloadId}").GetResponseAsync();
foreach (var proc in Process.GetProcessesByName("Remotely_Installer"))
@ -145,6 +143,8 @@ namespace Remotely.Agent.Services
proc.Kill();
}
Logger.Write("Launching installer to perform update.");
Process.Start(installerPath, $"-install -quiet -path {zipPath} -serverurl {serverUrl} -organizationid {connectionInfo.OrganizationID}");
}
else if (EnvironmentHelper.IsLinux)
@ -159,13 +159,19 @@ namespace Remotely.Agent.Services
serverUrl + $"/api/AgentUpdate/DownloadPackage/linux/{downloadId}",
zipPath);
WebRequest.CreateHttp(serverUrl + $"/api/AgentUpdate/ClearDownload/{downloadId}").GetResponse();
await WebRequest.CreateHttp(serverUrl + $"/api/AgentUpdate/ClearDownload/{downloadId}").GetResponseAsync();
Logger.Write("Launching installer to perform update.");
Process.Start("sudo", $"chmod +x {installerPath}").WaitForExit();
Process.Start("sudo", $"{installerPath} --path {zipPath} & disown");
}
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
{
Logger.Write("Timed out while waiting to downloaod update.", Shared.Enums.EventType.Warning);
}
catch (Exception ex)
{
Logger.Write(ex);

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Remotely.ScreenCast.Core;
using Remotely.ScreenCast.Core.Services;
using Remotely.Shared.Utilities;
using Remotely.Shared.Win32;
using System;
using System.Diagnostics;

View File

@ -19,6 +19,7 @@ using Remotely.ScreenCast.Core.Communication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Remotely.Shared.Win32;
using Remotely.Shared.Utilities;
namespace Remotely.Desktop.Win.ViewModels
{

View File

@ -10,6 +10,7 @@ using System.Net;
using Remotely.ScreenCast.Core.Services;
using Remotely.ScreenCast.Core.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Remotely.Shared.Utilities;
namespace Remotely.ScreenCast.Core.Communication
{

View File

@ -3,6 +3,7 @@ using Microsoft.MixedReality.WebRTC;
using Remotely.ScreenCast.Core.Services;
using Remotely.Shared.Models;
using Remotely.Shared.Models.RtcDtos;
using Remotely.Shared.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -7,6 +7,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using Remotely.Shared.Utilities;
namespace Remotely.ScreenCast.Core
{

View File

@ -2,6 +2,7 @@
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Services;
using Remotely.Shared.Models;
using Remotely.Shared.Utilities;
using System;
using System.Drawing.Imaging;
using System.Threading.Tasks;

View File

@ -1,4 +1,5 @@
using Remotely.ScreenCast.Core.Models;
using Remotely.Shared.Utilities;
using System;
using System.Collections.Concurrent;
using System.Timers;

View File

@ -4,6 +4,7 @@ using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Models;
using Remotely.Shared.Enums;
using Remotely.Shared.Models.RtcDtos;
using Remotely.Shared.Utilities;
using System;
using System.Collections.Generic;
using System.Dynamic;

View File

@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Linq;
using Remotely.ScreenCast.Core.Models;
using Remotely.Shared.Utilities;
namespace Remotely.ScreenCast.Linux
{

View File

@ -1,5 +1,6 @@
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Services;
using Remotely.Shared.Utilities;
using System;
using System.Diagnostics;
using System.IO;

View File

@ -3,6 +3,7 @@ using Remotely.ScreenCast.Core.Services;
using Remotely.ScreenCast.Linux.X11Interop;
using System;
using Remotely.ScreenCast.Core.Models;
using Remotely.Shared.Utilities;
namespace Remotely.ScreenCast.Linux.Services
{

View File

@ -1,6 +1,7 @@
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Services;
using Remotely.ScreenCast.Linux.X11Interop;
using Remotely.Shared.Utilities;
using System;
using System.Collections.Generic;
using System.Drawing;

View File

@ -12,6 +12,7 @@ using Remotely.ScreenCast.Core.Communication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Remotely.ScreenCast.Core.Models;
using Remotely.Shared.Utilities;
namespace Remotely.ScreenCast.Win
{

View File

@ -1,5 +1,6 @@
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Services;
using Remotely.Shared.Utilities;
using Remotely.Shared.Win32;
using System;
using System.Threading;

View File

@ -10,6 +10,7 @@ using System.Collections.Concurrent;
using System.Threading.Tasks;
using Remotely.ScreenCast.Core;
using System.Runtime.InteropServices;
using Remotely.Shared.Utilities;
namespace Remotely.ScreenCast.Win.Services
{

View File

@ -25,6 +25,7 @@ using Microsoft.Win32;
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Services;
using Remotely.ScreenCast.Win.Models;
using Remotely.Shared.Utilities;
using Remotely.Shared.Win32;
using SharpDX;
using SharpDX.Direct3D11;

View File

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Remotely.Server.Services;
using Remotely.Shared.Enums;
using System;
using System.IO;
using System.Net;
@ -13,7 +14,8 @@ namespace Remotely.Server.API
[ApiController]
public class AgentUpdateController : ControllerBase
{
private static readonly MemoryCache downloadingAgents = new MemoryCache(new MemoryCacheOptions());
private static readonly MemoryCache downloadingAgents = new MemoryCache(new MemoryCacheOptions()
{ ExpirationScanFrequency = TimeSpan.FromSeconds(10) });
public AgentUpdateController(IWebHostEnvironment hostingEnv,
@ -33,6 +35,7 @@ namespace Remotely.Server.API
[HttpGet("[action]/{downloadId}")]
public ActionResult ClearDownload(string downloadId)
{
DataService.WriteEvent($"Clearing download ID {downloadId}.", EventType.Debug, null);
downloadingAgents.Remove(downloadId);
return Ok();
}
@ -60,10 +63,12 @@ namespace Remotely.Server.API
await Task.Delay(new Random().Next(100, 10000));
}
var waitTime = DateTimeOffset.Now - startWait;
DataService.WriteEvent($"Download started after wait time of {waitTime}.", Shared.Models.EventType.Debug, string.Empty);
downloadingAgents.Set(downloadId, string.Empty, TimeSpan.FromMinutes(10));
DataService.WriteEvent($"Download started after wait time of {waitTime}. " + "" +
$"Current Downloads: {downloadingAgents.Count}. Max Allowed: {AppConfig.MaxConcurrentUpdates}", EventType.Debug, null);
byte[] fileBytes;
string filePath;
@ -89,6 +94,7 @@ namespace Remotely.Server.API
}
catch (Exception ex)
{
downloadingAgents.Remove(downloadId);
DataService.WriteEvent(ex, null);
return StatusCode((int)HttpStatusCode.InternalServerError);
}

View File

@ -12,6 +12,9 @@
<div class="row">
<div class="col-md-6">
<form id="serverConfigForm" method="post" autocomplete="off">
<div class="text-right">
<span class="badge badge-info p-2">Environment: @Model.Environment</span>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
<h4>Application Settings</h4>

View File

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Remotely.Server.Services;
using Remotely.Shared.Enums;
using Remotely.Shared.Models;
@ -41,6 +42,7 @@ namespace Remotely.Server.Areas.Identity.Pages.Account.Manage
public ConnectionStringsModel ConnectionStrings { get; set; } = new ConnectionStringsModel();
public bool IsServerAdmin { get; set; }
public string Environment { get; set; }
[BindProperty]
[Display(Name = "Server Admins")]
@ -57,6 +59,7 @@ namespace Remotely.Server.Areas.Identity.Pages.Account.Manage
public async Task<IActionResult> OnGet()
{
IsServerAdmin = (await UserManager.GetUserAsync(User)).IsServerAdmin;
Environment = HostEnv.EnvironmentName;
if (!IsServerAdmin)
{
return Unauthorized();
@ -104,11 +107,16 @@ namespace Remotely.Server.Areas.Identity.Pages.Account.Manage
{
string savePath;
var prodSettings = HostEnv.ContentRootFileProvider.GetFileInfo("appsettings.Production.json");
var stagingSettings = HostEnv.ContentRootFileProvider.GetFileInfo("appsettings.Staging.json");
var settings = HostEnv.ContentRootFileProvider.GetFileInfo("appsettings.json");
if (prodSettings.Exists)
if (HostEnv.IsProduction() && prodSettings.Exists)
{
savePath = prodSettings.PhysicalPath;
}
else if (HostEnv.IsStaging() && stagingSettings.Exists)
{
savePath = stagingSettings.PhysicalPath;
}
else if (settings.Exists)
{
savePath = settings.PhysicalPath;

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Remotely.Server.Services;
using Remotely.Shared.Enums;
namespace Remotely.Server.Pages
{
@ -41,7 +42,7 @@ namespace Remotely.Server.Pages
else if (!DataService.DoesUserHaveAccessToDevice(deviceID, user))
{
DataService.WriteEvent($"Edit device attempted by unauthorized user. Device ID: {deviceID}. User Name: {user.UserName}.",
Remotely.Shared.Models.EventType.Warning,
EventType.Warning,
targetDevice.OrganizationID);
return Unauthorized();
}

View File

@ -3,6 +3,7 @@ using Remotely.Server.Services;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Remotely.Shared.Enums;
namespace Remotely.Server.Pages
{
@ -33,7 +34,7 @@ namespace Remotely.Server.Pages
{
var logEntry = new Remotely.Shared.Models.EventLog()
{
EventType = Remotely.Shared.Models.EventType.Error,
EventType = EventType.Error,
Message = error.Message,
Source = error.Source,
StackTrace = error.StackTrace,

View File

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Remotely.Shared.Enums;
namespace Remotely.Server.Services
{

View File

@ -10,6 +10,7 @@ using Remotely.Shared.ViewModels.Organization;
using Remotely.Server.Data;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
using Remotely.Shared.Enums;
namespace Remotely.Server.Services
{
@ -638,16 +639,25 @@ namespace Remotely.Server.Services
public IEnumerable<EventLog> GetEventLogs(string userName, DateTimeOffset from, DateTimeOffset to)
{
var orgID = RemotelyContext.Users
.FirstOrDefault(x => x.UserName == userName)
?.OrganizationID;
var user = RemotelyContext.Users
.FirstOrDefault(x => x.UserName == userName);
var fromDate = from.Date;
var toDate = to.Date.AddDays(1);
return RemotelyContext.EventLogs
.Where(x => x.OrganizationID == orgID && x.TimeStamp >= fromDate && x.TimeStamp <= toDate)
.OrderByDescending(x => x.TimeStamp);
if (user.IsServerAdmin)
{
return RemotelyContext.EventLogs
.Where(x => x.TimeStamp >= fromDate && x.TimeStamp <= toDate)
.OrderByDescending(x => x.TimeStamp);
}
else
{
var orgID = user.OrganizationID;
return RemotelyContext.EventLogs
.Where(x => x.OrganizationID == orgID && x.TimeStamp >= fromDate && x.TimeStamp <= toDate)
.OrderByDescending(x => x.TimeStamp);
}
}
public int GetOrganizationCount()

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Remotely.Shared.Enums;
namespace Remotely.Server.Services
{

14
Shared/Enums/EventType.cs Normal file
View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Remotely.Shared.Enums
{
public enum EventType
{
Info = 0,
Error = 1,
Debug = 2,
Warning = 3
}
}

View File

@ -1,4 +1,5 @@
using System;
using Remotely.Shared.Enums;
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
@ -17,11 +18,4 @@ namespace Remotely.Shared.Models
[JsonIgnore]
public Organization Organization { get; set; }
}
public enum EventType
{
Info = 0,
Error = 1,
Debug = 2,
Warning = 3
}
}

View File

@ -1,10 +1,12 @@
using System;
using Remotely.Shared.Enums;
using Remotely.Shared.Utilities;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace Remotely.ScreenCast.Core.Services
namespace Remotely.Shared.Utilities
{
public static class Logger
{
@ -14,32 +16,33 @@ namespace Remotely.ScreenCast.Core.Services
{
lock (WriteLock)
{
#if DEBUG
CheckLogFileExists();
if (EnvironmentHelper.IsDebug)
{
CheckLogFileExists();
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[DEBUG]\t{message}{Environment.NewLine}");
#endif
File.AppendAllText(LogPath, $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff}\t[Debug]\t{message}{Environment.NewLine}");
}
System.Diagnostics.Debug.WriteLine(message);
}
}
public static void Write(string message)
public static void Write(string message, EventType eventType = EventType.Info)
{
try
{
lock (WriteLock)
{
CheckLogFileExists();
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[INFO]\t{message}{Environment.NewLine}");
File.AppendAllText(LogPath, $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff}\t[{eventType}]\t{message}{Environment.NewLine}");
Console.WriteLine(message);
}
}
catch { }
}
public static void Write(Exception ex)
public static void Write(Exception ex, EventType eventType = EventType.Error)
{
lock (WriteLock)
{
@ -51,7 +54,7 @@ namespace Remotely.ScreenCast.Core.Services
while (exception != null)
{
File.AppendAllText(LogPath, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\t[ERROR]\t{exception?.Message}\t{exception?.StackTrace}\t{exception?.Source}{Environment.NewLine}");
File.AppendAllText(LogPath, $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff}\t[{eventType}]\t{exception?.Message}\t{exception?.StackTrace}\t{exception?.Source}{Environment.NewLine}");
Console.WriteLine(exception.Message);
exception = exception.InnerException;
}
@ -60,6 +63,12 @@ namespace Remotely.ScreenCast.Core.Services
}
}
public static void Write(Exception ex, string message, EventType eventType = EventType.Error)
{
Write(message, eventType);
Write(ex, eventType);
}
private static void CheckLogFileExists()
{
if (!File.Exists(LogPath))