Sentry Integration (#212)

* Fixed a parsing case

* Integrated Sentry into the solution with anonymous users. Fixed some parsing issues and added BuildInfo into a separate project.

* Fixed some bad parser regex

* Removed bad reference to NLog

* Cleanup of some files not needed
This commit is contained in:
Joseph Milazzo 2021-05-11 14:45:18 -05:00 committed by GitHub
parent 6fc5e535df
commit c8adaee3eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 463 additions and 29 deletions

View file

@ -12,6 +12,23 @@
<ApplicationIcon>../favicon.ico</ApplicationIcon>
</PropertyGroup>
<!-- Set the Product and Version info for our own projects -->
<PropertyGroup>
<Product>Kavita</Product>
<Company>kareadita.github.io</Company>
<Copyright>Copyright 2020-$([System.DateTime]::Now.ToString('yyyy')) kareadita.github.io (GNU General Public v3)</Copyright>
<!-- Should be replaced by CI -->
<AssemblyVersion>0.4.1</AssemblyVersion>
<AssemblyConfiguration>$(Configuration)-dev</AssemblyConfiguration>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<Deterministic Condition="$(AssemblyVersion.EndsWith('*'))">False</Deterministic>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" />
<PackageReference Include="ExCSS" Version="4.1.0" />
@ -33,6 +50,7 @@
<PackageReference Include="NetVips" Version="2.0.0" />
<PackageReference Include="NetVips.Native" Version="8.10.6" />
<PackageReference Include="NReco.Logging.File" Version="1.1.1" />
<PackageReference Include="Sentry.AspNetCore" Version="3.3.4" />
<PackageReference Include="SharpCompress" Version="0.28.1" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.20.0.28934">
<PrivateAssets>all</PrivateAssets>
@ -65,4 +83,8 @@
<_ContentIncludedByDefault Remove="logs\kavita.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Kavita.Common\Kavita.Common.csproj" />
</ItemGroup>
</Project>

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using API.DTOs;
using API.Entities;
@ -148,6 +149,7 @@ namespace API.Controllers
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetRecentlyAdded(int libraryId = 0, int limit = 20)
{
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
if (user == null) return Ok(Array.Empty<SeriesDto>());
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyAdded(user.Id, libraryId, limit));
}
@ -155,6 +157,7 @@ namespace API.Controllers
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetInProgress(int libraryId = 0, int limit = 20)
{
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
if (user == null) return Ok(Array.Empty<SeriesDto>());
return Ok(await _unitOfWork.SeriesRepository.GetInProgress(user.Id, libraryId, limit));
}

View file

@ -1,20 +1,40 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
#This Dockerfile pulls the latest git commit and builds Kavita from source
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS builder
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["API/API.csproj", "API/"]
RUN dotnet restore "API/API.csproj"
COPY . .
WORKDIR "/src/API"
RUN dotnet build "API.csproj" -c Release -o /app/build
ENV DEBIAN_FRONTEND=noninteractive
ARG TARGETPLATFORM
FROM build AS publish
RUN dotnet publish "API.csproj" -c Release -o /app/publish
#Installs nodejs and npm
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API.dll"]
#Builds app based on platform
COPY build_target.sh /build_target.sh
RUN /build_target.sh
#Production image
FROM ubuntu:focal
#Move the output files to where they need to be
COPY --from=builder /Projects/Kavita/_output/build/Kavita /kavita
#Installs program dependencies
RUN apt-get update \
&& apt-get install -y libicu-dev libssl1.1 pwgen \
&& rm -rf /var/lib/apt/lists/*
#Creates the manga storage directory
RUN mkdir /manga /kavita/data
RUN cp /kavita/appsettings.Development.json /kavita/appsettings.json \
&& sed -i 's/Data source=kavita.db/Data source=data\/kavita.db/g' /kavita/appsettings.json
COPY entrypoint.sh /entrypoint.sh
EXPOSE 5000
WORKDIR /kavita
ENTRYPOINT ["/bin/bash"]
CMD ["/entrypoint.sh"]

View file

@ -92,7 +92,7 @@ namespace API.Parser
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Momo The Blood Taker - Chapter 027 Violent Emotion.cbz
new Regex(
@"(?<Series>.*) (\b|_|-)(?:chapter)",
@"(?<Series>.*)(\b|_|-|\s)(?:chapter)(\b|_|-|\s)\d",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Historys Strongest Disciple Kenichi_v11_c90-98.zip, Killing Bites Vol. 0001 Ch. 0001 - Galactica Scanlations (gb)
new Regex(
@ -101,7 +101,7 @@ namespace API.Parser
//Ichinensei_ni_Nacchattara_v01_ch01_[Taruby]_v1.1.zip must be before [Suihei Kiki]_Kasumi_Otoko_no_Ko_[Taruby]_v1.1.zip
// due to duplicate version identifiers in file.
new Regex(
@"(?<Series>.*)(v|s)\d+(-\d+)?(_| )",
@"(?<Series>.*)(v|s)\d+(-\d+)?(_|\s)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//[Suihei Kiki]_Kasumi_Otoko_no_Ko_[Taruby]_v1.1.zip
new Regex(
@ -121,7 +121,7 @@ namespace API.Parser
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Tonikaku Kawaii (Ch 59-67) (Ongoing)
new Regex(
@"(?<Series>.*)( |_)\((c |ch |chapter )",
@"(?<Series>.*)(\s|_)\((c\s|ch\s|chapter\s)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// Black Bullet (This is very loose, keep towards bottom)
new Regex(
@ -364,7 +364,7 @@ namespace API.Parser
{
// All Keywords, does not account for checking if contains volume/chapter identification. Parser.Parse() will handle.
new Regex(
@"(?<Special>Specials?|OneShot|One\-Shot|Omake|Extra( Chapter)?|Art Collection|Side( |_)Stories)",
@"(?<Special>Specials?|OneShot|One\-Shot|Omake|Extra( Chapter)?|Art Collection|Side( |_)Stories|(?<!The\s)Anthology)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
};

View file

@ -1,7 +1,11 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using API.Data;
using API.Entities;
using Kavita.Common;
using Kavita.Common.EnvironmentInfo;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.Kestrel.Core;
@ -9,18 +13,22 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Sentry;
namespace API
{
public class Program
{
private static readonly int HttpPort = 5000;
protected Program()
{
}
public static async Task Main(string[] args)
{
// Before anything, check if JWT has been generated properly or if user still has default
var host = CreateHostBuilder(args).Build();
using var scope = host.Services.CreateScope();
@ -55,6 +63,36 @@ namespace API
options.Protocols = HttpProtocols.Http1AndHttp2;
});
});
webBuilder.UseSentry(options =>
{
options.Dsn = "https://40f4e7b49c094172a6f99d61efb2740f@o641015.ingest.sentry.io/5757423";
options.MaxBreadcrumbs = 200;
options.AttachStacktrace = true;
options.Debug = false;
options.SendDefaultPii = false;
options.DiagnosticLevel = SentryLevel.Debug;
options.ShutdownTimeout = TimeSpan.FromSeconds(5);
options.Release = BuildInfo.Version.ToString();
options.AddExceptionFilterForType<OutOfMemoryException>();
options.AddExceptionFilterForType<NetVips.VipsException>();
options.AddExceptionFilterForType<InvalidDataException>();
options.ConfigureScope(scope =>
{
scope.User = new User()
{
Id = HashUtil.AnonymousToken()
};
scope.Contexts.App.Name = BuildInfo.AppName;
scope.Contexts.App.Version = BuildInfo.Version.ToString();
scope.Contexts.App.StartTime = DateTime.UtcNow;
scope.Contexts.App.Hash = HashUtil.AnonymousToken();
scope.Contexts.App.Build = BuildInfo.Release;
scope.SetTag("culture", Thread.CurrentThread.CurrentCulture.Name);
scope.SetTag("branch", BuildInfo.Branch);
});
});
webBuilder.UseStartup<Startup>();
});
}

View file

@ -1,12 +1,14 @@
using System;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using API.Extensions;
using API.Interfaces;
using API.Middleware;
using API.Services;
using Hangfire;
using Hangfire.MemoryStorage;
using Kavita.Common.EnvironmentInfo;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -131,7 +133,7 @@ namespace API
applicationLifetime.ApplicationStopping.Register(OnShutdown);
applicationLifetime.ApplicationStarted.Register(() =>
{
Console.WriteLine("Kavita - v0.4.1");
Console.WriteLine("Kavita - v" + BuildInfo.Version);
});
// Any services that should be bootstrapped go here
@ -140,10 +142,10 @@ namespace API
private void OnShutdown()
{
Console.WriteLine("Server is shutting down. Going to dispose Hangfire");
//this code is called when the application stops
Console.WriteLine("Server is shutting down. Please allow a few seconds to stop any background jobs...");
TaskScheduler.Client.Dispose();
System.Threading.Thread.Sleep(1000);
Console.WriteLine("You may now close the application window.");
}
}
}