global: migrate to using ILogger

This commit is contained in:
Abdullah Atta
2025-10-14 09:28:41 +05:00
parent 0cc3365e44
commit be432dfd24
14 changed files with 113 additions and 161 deletions

View File

@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using Notesnook.API.Interfaces;
using Notesnook.API.Models;
@@ -74,24 +75,24 @@ namespace Notesnook.API.Accessors
IMongoCollection<SyncItem> tags,
Repository<UserSettings> usersSettings, Repository<Monograph> monographs,
Repository<InboxApiKey> inboxApiKey, Repository<InboxSyncItem> inboxItems)
Repository<InboxApiKey> inboxApiKey, Repository<InboxSyncItem> inboxItems, ILogger<SyncItemsRepository> logger)
{
UsersSettings = usersSettings;
Monographs = monographs;
InboxApiKey = inboxApiKey;
InboxItems = inboxItems;
Notebooks = new SyncItemsRepository(dbContext, notebooks);
Notes = new SyncItemsRepository(dbContext, notes);
Contents = new SyncItemsRepository(dbContext, content);
Settings = new SyncItemsRepository(dbContext, settings);
LegacySettings = new SyncItemsRepository(dbContext, legacySettings);
Attachments = new SyncItemsRepository(dbContext, attachments);
Shortcuts = new SyncItemsRepository(dbContext, shortcuts);
Reminders = new SyncItemsRepository(dbContext, reminders);
Relations = new SyncItemsRepository(dbContext, relations);
Colors = new SyncItemsRepository(dbContext, colors);
Vaults = new SyncItemsRepository(dbContext, vaults);
Tags = new SyncItemsRepository(dbContext, tags);
Notebooks = new SyncItemsRepository(dbContext, notebooks, logger);
Notes = new SyncItemsRepository(dbContext, notes, logger);
Contents = new SyncItemsRepository(dbContext, content, logger);
Settings = new SyncItemsRepository(dbContext, settings, logger);
LegacySettings = new SyncItemsRepository(dbContext, legacySettings, logger);
Attachments = new SyncItemsRepository(dbContext, attachments, logger);
Shortcuts = new SyncItemsRepository(dbContext, shortcuts, logger);
Reminders = new SyncItemsRepository(dbContext, reminders, logger);
Relations = new SyncItemsRepository(dbContext, relations, logger);
Colors = new SyncItemsRepository(dbContext, colors, logger);
Vaults = new SyncItemsRepository(dbContext, vaults, logger);
Tags = new SyncItemsRepository(dbContext, tags, logger);
}
}
}

View File

@@ -23,6 +23,7 @@ using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;
using Notesnook.API.Authorization;
using Notesnook.API.Models;
@@ -35,21 +36,12 @@ namespace Notesnook.API.Controllers
{
[ApiController]
[Route("inbox")]
public class InboxController : ControllerBase
{
private readonly Repository<InboxApiKey> InboxApiKey;
private readonly Repository<UserSettings> UserSetting;
private Repository<InboxSyncItem> InboxItems;
public InboxController(
public class InboxController(
Repository<InboxApiKey> inboxApiKeysRepository,
Repository<UserSettings> userSettingsRepository,
Repository<InboxSyncItem> inboxItemsRepository)
{
InboxApiKey = inboxApiKeysRepository;
UserSetting = userSettingsRepository;
InboxItems = inboxItemsRepository;
}
Repository<InboxSyncItem> inboxItemsRepository,
ILogger<InboxController> logger) : ControllerBase
{
[HttpGet("api-keys")]
[Authorize(Policy = "Notesnook")]
@@ -58,12 +50,12 @@ namespace Notesnook.API.Controllers
var userId = User.FindFirstValue("sub");
try
{
var apiKeys = await InboxApiKey.FindAsync(t => t.UserId == userId);
var apiKeys = await inboxApiKeysRepository.FindAsync(t => t.UserId == userId);
return Ok(apiKeys);
}
catch (Exception ex)
{
await Slogger<InboxController>.Error(nameof(GetApiKeysAsync), "Couldn't get inbox api keys.", userId, ex.ToString());
logger.LogError(ex, "Couldn't get inbox api keys for user {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}
@@ -84,7 +76,7 @@ namespace Notesnook.API.Controllers
return BadRequest(new { error = "Valid expiry date is required." });
}
var count = await InboxApiKey.CountAsync(t => t.UserId == userId);
var count = await inboxApiKeysRepository.CountAsync(t => t.UserId == userId);
if (count >= 10)
{
return BadRequest(new { error = "Maximum of 10 inbox api keys allowed." });
@@ -98,12 +90,12 @@ namespace Notesnook.API.Controllers
ExpiryDate = request.ExpiryDate,
LastUsedAt = 0
};
await InboxApiKey.InsertAsync(inboxApiKey);
await inboxApiKeysRepository.InsertAsync(inboxApiKey);
return Ok(inboxApiKey);
}
catch (Exception ex)
{
await Slogger<InboxController>.Error(nameof(CreateApiKeyAsync), "Couldn't create inbox api key.", userId, ex.ToString());
logger.LogError(ex, "Couldn't create inbox api key for {UserId}.", userId);
return BadRequest(new { error = ex.Message });
}
}
@@ -120,12 +112,12 @@ namespace Notesnook.API.Controllers
return BadRequest(new { error = "Api key is required." });
}
await InboxApiKey.DeleteAsync(t => t.UserId == userId && t.Key == apiKey);
await inboxApiKeysRepository.DeleteAsync(t => t.UserId == userId && t.Key == apiKey);
return Ok(new { message = "Api key deleted successfully." });
}
catch (Exception ex)
{
await Slogger<InboxController>.Error(nameof(DeleteApiKeyAsync), "Couldn't delete inbox api key.", userId, ex.ToString());
logger.LogError(ex, "Couldn't delete inbox api key for user {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}
@@ -137,7 +129,7 @@ namespace Notesnook.API.Controllers
var userId = User.FindFirstValue("sub");
try
{
var userSetting = await UserSetting.FindOneAsync(u => u.UserId == userId);
var userSetting = await userSettingsRepository.FindOneAsync(u => u.UserId == userId);
if (string.IsNullOrWhiteSpace(userSetting?.InboxKeys?.Public))
{
return BadRequest(new { error = "Inbox public key is not configured." });
@@ -146,7 +138,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<InboxController>.Error(nameof(GetPublicKeyAsync), "Couldn't get user's inbox's public key.", userId, ex.ToString());
logger.LogError(ex, "Couldn't get user's inbox's public key for user {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}
@@ -189,7 +181,7 @@ namespace Notesnook.API.Controllers
request.UserId = userId;
request.ItemId = ObjectId.GenerateNewId().ToString();
await InboxItems.InsertAsync(request);
await inboxItemsRepository.InsertAsync(request);
new SyncDeviceService(new SyncDevice(userId, string.Empty))
.AddIdsToAllDevices([$"{request.ItemId}:inboxItems"]);
await WampServers.MessengerServer.PublishMessageAsync(MessengerServerTopics.SendSSETopic, new SendSSEMessage
@@ -206,7 +198,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<InboxController>.Error(nameof(CreateInboxItemAsync), "Couldn't create inbox item.", userId, ex.ToString());
logger.LogError(ex, "Couldn't create inbox item for user {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}

View File

@@ -27,6 +27,7 @@ using AngleSharp;
using AngleSharp.Dom;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;
using MongoDB.Driver;
using Notesnook.API.Authorization;
@@ -43,7 +44,7 @@ namespace Notesnook.API.Controllers
[ApiController]
[Route("monographs")]
[Authorize("Sync")]
public class MonographsController(Repository<Monograph> monographs, IURLAnalyzer analyzer) : ControllerBase
public class MonographsController(Repository<Monograph> monographs, IURLAnalyzer analyzer, ILogger<MonographsController> logger) : ControllerBase
{
const string SVG_PIXEL = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><circle r='9'/></svg>";
private const int MAX_DOC_SIZE = 15 * 1024 * 1024;
@@ -133,7 +134,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception e)
{
await Slogger<MonographsController>.Error(nameof(PublishAsync), e.ToString());
logger.LogError(e, "Failed to publish monograph");
return BadRequest();
}
}
@@ -184,7 +185,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception e)
{
await Slogger<MonographsController>.Error(nameof(UpdateAsync), e.ToString());
logger.LogError(e, "Failed to update monograph");
return BadRequest();
}
}
@@ -328,7 +329,7 @@ namespace Notesnook.API.Controllers
if (string.IsNullOrEmpty(href)) continue;
if (!await analyzer.IsURLSafeAsync(href))
{
await Slogger<MonographsController>.Info("CleanupContentAsync", "Malicious URL detected: " + href);
logger.LogInformation("Malicious URL detected: {Url}", href);
element.RemoveAttribute("href");
}
}
@@ -355,7 +356,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<MonographsController>.Error("CleanupContentAsync", ex.ToString());
logger.LogError(ex, "Failed to cleanup monograph content");
return content;
}
}

View File

@@ -24,6 +24,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Notesnook.API.Interfaces;
using Notesnook.API.Models.Responses;
using Notesnook.API.Services;
@@ -36,10 +37,10 @@ namespace Notesnook.API.Controllers
[ApiController]
[Authorize]
[Route("devices")]
public class SyncDeviceController : ControllerBase
public class SyncDeviceController(ILogger<SyncDeviceController> logger) : ControllerBase
{
[HttpPost]
public async Task<IActionResult> RegisterDevice([FromQuery] string deviceId)
public IActionResult RegisterDevice([FromQuery] string deviceId)
{
try
{
@@ -49,14 +50,14 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<UsersController>.Error(nameof(UnregisterDevice), "Couldn't register device.", ex.ToString());
logger.LogError(ex, "Failed to register device: {DeviceId}", deviceId);
return BadRequest(new { error = ex.Message });
}
}
[HttpDelete]
public async Task<IActionResult> UnregisterDevice([FromQuery] string deviceId)
public IActionResult UnregisterDevice([FromQuery] string deviceId)
{
try
{
@@ -66,7 +67,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<UsersController>.Error(nameof(UnregisterDevice), "Couldn't unregister device.", ex.ToString());
logger.LogError(ex, "Failed to unregister device: {DeviceId}", deviceId);
return BadRequest(new { error = ex.Message });
}
}

View File

@@ -23,6 +23,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Timeouts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Notesnook.API.Interfaces;
using Notesnook.API.Models;
using Notesnook.API.Models.Responses;
@@ -33,7 +34,7 @@ namespace Notesnook.API.Controllers
[ApiController]
[Authorize]
[Route("users")]
public class UsersController(IUserService UserService) : ControllerBase
public class UsersController(IUserService UserService, ILogger<UsersController> logger) : ControllerBase
{
[HttpPost]
[AllowAnonymous]
@@ -46,7 +47,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<UsersController>.Error(nameof(Signup), "Couldn't sign up.", ex.ToString());
logger.LogError(ex, "Failed to sign up user");
return BadRequest(new { error = ex.Message });
}
}
@@ -63,7 +64,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<UsersController>.Error(nameof(GetUser), "Couldn't get user for id.", userId, ex.ToString());
logger.LogError(ex, "Failed to get user with id: {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}
@@ -79,7 +80,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<UsersController>.Error(nameof(GetUser), "Couldn't update user with id.", userId, ex.ToString());
logger.LogError(ex, "Failed to update user with id: {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}
@@ -107,7 +108,7 @@ namespace Notesnook.API.Controllers
}
catch (Exception ex)
{
await Slogger<UsersController>.Error(nameof(GetUser), "Couldn't delete user with id.", userId, ex.ToString());
logger.LogError(ex, "Failed to delete user with id: {UserId}", userId);
return BadRequest(new { error = ex.Message });
}
}

View File

@@ -26,6 +26,7 @@ using System.Threading;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.VisualBasic;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;
using MongoDB.Driver;
using Notesnook.API.Hubs;
@@ -41,9 +42,11 @@ namespace Notesnook.API.Repositories
public class SyncItemsRepository : Repository<SyncItem>
{
private readonly string collectionName;
public SyncItemsRepository(IDbContext dbContext, IMongoCollection<SyncItem> collection) : base(dbContext, collection)
private readonly ILogger<SyncItemsRepository> logger;
public SyncItemsRepository(IDbContext dbContext, IMongoCollection<SyncItem> collection, ILogger<SyncItemsRepository> logger) : base(dbContext, collection)
{
this.collectionName = collection.CollectionNamespace.CollectionName;
this.logger = logger;
}
private readonly List<string> ALGORITHMS = [Algorithms.Default, Algorithms.XSAL_X25519_7];
@@ -110,7 +113,8 @@ namespace Notesnook.API.Repositories
// Handle case where the cipher is corrupted.
if (!IsBase64String(item.Cipher))
{
Slogger<SyncHub>.Error("Upsert", "Corrupted", item.ItemId, item.Length.ToString(), item.Cipher);
logger.LogError("Corrupted item {ItemId} in collection {CollectionName}. Length: {Length}, Cipher: {Cipher}",
item.ItemId, this.collectionName, item.Length, item.Cipher);
throw new Exception($"Corrupted item \"{item.ItemId}\" in collection \"{this.collectionName}\". Please report this error to support@streetwriters.co.");
}
@@ -147,7 +151,8 @@ namespace Notesnook.API.Repositories
// Handle case where the cipher is corrupted.
if (!IsBase64String(item.Cipher))
{
Slogger<SyncHub>.Error("Upsert", "Corrupted", item.ItemId, item.Length.ToString(), item.Cipher);
logger.LogError("Corrupted item {ItemId} in collection {CollectionName}. Length: {Length}, Cipher: {Cipher}",
item.ItemId, this.collectionName, item.Length, item.Cipher);
throw new Exception($"Corrupted item \"{item.ItemId}\" in collection \"{this.collectionName}\". Please report this error to support@streetwriters.co.");
}

View File

@@ -23,6 +23,7 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Notesnook.API.Helpers;
using Notesnook.API.Interfaces;
using Notesnook.API.Models;
@@ -37,33 +38,23 @@ using Streetwriters.Data.Interfaces;
namespace Notesnook.API.Services
{
public class UserService : IUserService
public class UserService(IHttpContextAccessor accessor,
ISyncItemsRepositoryAccessor syncItemsRepositoryAccessor,
IUnitOfWork unitOfWork, IS3Service s3Service, ILogger<UserService> logger) : IUserService
{
private static readonly System.Security.Cryptography.RandomNumberGenerator Rng = System.Security.Cryptography.RandomNumberGenerator.Create();
private readonly HttpClient httpClient;
private IHttpContextAccessor HttpContextAccessor { get; }
private ISyncItemsRepositoryAccessor Repositories { get; }
private IS3Service S3Service { get; set; }
private readonly IUnitOfWork unit;
public UserService(IHttpContextAccessor accessor,
ISyncItemsRepositoryAccessor syncItemsRepositoryAccessor,
IUnitOfWork unitOfWork, IS3Service s3Service)
{
httpClient = new HttpClient();
Repositories = syncItemsRepositoryAccessor;
HttpContextAccessor = accessor;
unit = unitOfWork;
S3Service = s3Service;
}
private readonly HttpClient httpClient = new();
private IHttpContextAccessor HttpContextAccessor { get; } = accessor;
private ISyncItemsRepositoryAccessor Repositories { get; } = syncItemsRepositoryAccessor;
private IS3Service S3Service { get; set; } = s3Service;
private readonly IUnitOfWork unit = unitOfWork;
public async Task CreateUserAsync()
{
SignupResponse response = await httpClient.ForwardAsync<SignupResponse>(this.HttpContextAccessor, $"{Servers.IdentityServer}/signup", HttpMethod.Post);
if (!response.Success || (response.Errors != null && response.Errors.Length > 0))
{
await Slogger<UserService>.Error(nameof(CreateUserAsync), "Couldn't sign up.", JsonSerializer.Serialize(response));
logger.LogError("Failed to sign up user: {Response}", JsonSerializer.Serialize(response));
if (response.Errors != null && response.Errors.Length > 0)
throw new Exception(string.Join(" ", response.Errors));
else throw new Exception("Could not create a new account. Error code: " + response.StatusCode);
@@ -91,7 +82,7 @@ namespace Notesnook.API.Services
});
}
await Slogger<UserService>.Info(nameof(CreateUserAsync), "New user created.", JsonSerializer.Serialize(response));
logger.LogInformation("New user created: {Response}", JsonSerializer.Serialize(response));
}
public async Task<UserResponse> GetUserAsync(string userId)
@@ -210,7 +201,7 @@ namespace Notesnook.API.Services
Repositories.InboxApiKey.DeleteMany((t) => t.UserId == userId);
var result = await unit.Commit();
await Slogger<UserService>.Info(nameof(DeleteUserAsync), "User data deleted", userId, result.ToString());
logger.LogInformation("User data deleted for user {UserId}: {Result}", userId, result);
if (!result) throw new Exception("Could not delete user data.");
if (!Constants.IS_SELF_HOSTED)
@@ -227,7 +218,7 @@ namespace Notesnook.API.Services
public async Task DeleteUserAsync(string userId, string jti, string password)
{
await Slogger<UserService>.Info(nameof(DeleteUserAsync), "Deleting user account", userId);
logger.LogInformation("Deleting user account: {UserId}", userId);
var userService = await WampServers.IdentityServer.GetServiceAsync<IUserAccountService>(IdentityServerTopics.UserAccountServiceTopic);
await userService.DeleteUserAsync(Clients.Notesnook.Id, userId, password);