public void Init() { try { if (File.Exists(InlinePluginManifestPath)) { var json = File.ReadAllText(InlinePluginManifestPath); if (!string.IsNullOrWhiteSpace(json)) { var entries = JsonConvert.DeserializeObject <InlineModuleManifestEntry[]>(json); _entries = new List <InlineModuleManifestEntry>(entries); Entries = _entries.AsReadOnly(); } else { _entries = new List <InlineModuleManifestEntry>(); Entries = _entries.AsReadOnly(); } } else { _entries = new List <InlineModuleManifestEntry>(); Entries = _entries.AsReadOnly(); } } catch (Exception ex) { ExceptionLogger.LogException(ex); SessionLog.Exception(ex); } }
private static async Task <bool> ValidateGoogleRecaptchaAsync(string captcha) /*Promise<{ success: boolean, "error-codes"?: string[]}>*/ { try { var postData = $"secret={Settings.SettingsInstance.Instance.Settings.GoogleRecaptchaSecret}&response={captcha}"; var webClient = new WebClient(); webClient.Headers["Content-Type"] = "application/x-www-form-urlencoded"; var responseBytes = await webClient.UploadDataTaskAsync("https://www.google.com/recaptcha/api/siteverify", "POST", System.Text.Encoding.UTF8.GetBytes(postData)); var response = System.Text.Encoding.UTF8.GetString(responseBytes); var deserialized = System.Text.Json.JsonSerializer.Deserialize <Dictionary <string, object> >(response); if (deserialized != null && deserialized["success"] != null) { var je = ((JsonElement)deserialized["success"]); return(je.GetBoolean()); } else { return(false); } } catch (Exception ex) { ExceptionLogger.LogException(ex); return(false); } /* * * * * request.post('https://www.google.com/recaptcha/api/siteverify', * { * headers: { 'content-type': 'application/json' }, * form: postData * }, (error: any, response: request.RequestResponse, body: any) => { * if (!error) { * try { * resolve(JSON.parse(body)); * } * catch (e) { * ExceptionLogger.logException(e); * reject(e); * } * } * else { * reject(error); * } * * });*/ }
public static ApiResponse Exception(Exception ex, string additionalInfo = null, string appTitle = null, string appVersion = null) { var id = ExceptionLogger.LogException(ex, additionalInfo, appTitle, appVersion); var ret = new ApiResponse(); ret.Message = $"Error ref: {id}"; ret.Type = ApiResponseType.Exception; ret.Data = new System.Dynamic.ExpandoObject(); ((dynamic)ret.Data).Ref = id; return(ret); }
public static ApiResponse ExecException(Exception ex, Controllers.ExecController.ExecOptions execOptions, out string exceptionId, string additionalInfo = null, string appTitle = null, string appVersion = null) { exceptionId = ExceptionLogger.LogException(ex, execOptions, additionalInfo, appTitle, appVersion); var ret = new ApiResponse(); ret.Message = $"Error ref: {exceptionId}"; ret.Type = ApiResponseType.Exception; ret.Data = new System.Dynamic.ExpandoObject(); ((dynamic)ret.Data).Ref = exceptionId; return(ret); }
public static async Task LogServerUptimeAsync() { try { using (var fs = File.Open(FullFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read)) { fs.Seek(0, SeekOrigin.End); async Task WriteTotalSecondsAsync() { var totalSeconds = (int)DateTime.Now.Subtract(Program.StartDate.Value).TotalSeconds; var str = totalSeconds.ToString().PadLeft(10); var buffer = Enc.UTF8.GetBytes(str); await fs.WriteAsync(buffer, 0, buffer.Length); await fs.FlushAsync(Program.CTS.Token); } var buffer = Enc.UTF8.GetBytes($"{DateTime.Now:yyyyMMddHHmmss}"); // write start date & time await fs.WriteAsync(buffer, 0, buffer.Length); var pos = fs.Position; await WriteTotalSecondsAsync(); buffer = Enc.UTF8.GetBytes("\n"); await fs.WriteAsync(buffer, 0, buffer.Length); while (!Program.CTS.IsCancellationRequested) { // move back to just after date & time fs.Seek(pos, SeekOrigin.Begin); await WriteTotalSecondsAsync(); await Task.Delay(5000, Program.CTS.Token); } } } catch (TaskCanceledException) { } catch (Exception ex) { ExceptionLogger.LogException(ex); } }
private static void ProcessPlugins(List <ExecutionPlugin> pluginList, SqlConnection con) { foreach (var plugin in pluginList) { try { plugin.OnConnectionOpened(con); } catch (Exception ex) { ExceptionLogger.LogException(ex, $"Plugin {plugin.Name} OnConnectionOpened failed", "jsdal-server"); } } }
public static ApiResponseServerMethodBase Exception(Exception ex) { SessionLog.Exception(ex); // TODO: Record ServerMethod detail var id = ExceptionLogger.LogException(ex, (Controllers.ExecController.ExecOptions)null); var ret = new ApiResponseServerMethodBase(); ret.Error = $"Error ref: {id}"; ret.Type = ApiResponseType.Exception; return(ret); }
static SessionLog() { try { var path = $"./log/session-log"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var filename = $"{DateTime.Now:yyyy-MM-dd HHmm}.txt"; _fs = File.Open(Path.Combine(path, filename), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read); } catch (Exception ex) { ExceptionLogger.LogException(ex); } }
static UptimeLogger() { try { var path = $"./log"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var filename = $"run.log"; FullFilePath = Path.Combine(path, filename); } catch (Exception ex) { ExceptionLogger.LogException(ex); } }
public static void Start() { try { var endpoints = SettingsInstance.Instance.ProjectList.SelectMany(p => p.Applications).SelectMany(app => app.Endpoints).ToList(); WorkSpawner.TEMPLATE_RoutineContainer = File.ReadAllText("./resources/RoutineContainerTemplate.txt"); WorkSpawner.TEMPLATE_Routine = File.ReadAllText("./resources/RoutineTemplate.txt"); WorkSpawner.TEMPLATE_TypescriptDefinitions = File.ReadAllText("./resources/TypeScriptDefinitionsContainer.d.ts"); WorkSpawner._workerList = new List <Worker>(); //dbSources = new DatabaseSource[] { dbSources.First() }.ToList(); //TEMP // TODO: handle items (project/sources) that were deleted //async.each(dbSources, (source) => { endpoints.ForEach(endpoint => { //TEST!! // if (endpoint.Name != "DEV" || endpoint.Application.Name != "PWAs") return; try { CreateNewWorker(endpoint); } catch (Exception e) { Log.Error(e, $"Failed to create new work for {endpoint.Pedigree}"); ExceptionLogger.LogException(e); } }); Hubs.WorkerMonitor.Instance.NotifyObservers(); } catch (Exception e) { SessionLog.Exception(e); Log.Error(e, "Work spawner error on start"); } } // Start
public static void Main(string[] args) { IsShuttingDown = false; var loggerConfig = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.File("log/detail-.txt", //?restrictedToMinimumLevel: LogEventLevel.Warning, rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7, shared: true, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3} {Message:lj}{NewLine}{Exception}" ) // .WriteTo.File("log/info-.txt", // rollingInterval: RollingInterval.Day, // shared: true, // outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3} {Message:lj}{NewLine}{Exception}", // restrictedToMinimumLevel: LogEventLevel.Information // ) ; try { CTS = new CancellationTokenSource(); var isService = args.Length == 1 && args[0].Equals("--service", StringComparison.OrdinalIgnoreCase); var justRun = args.Length == 1 && args[0].Equals("--run", StringComparison.OrdinalIgnoreCase); if (isService) { var pathToExe = Process.GetCurrentProcess().MainModule.FileName; var pathToContentRootService = Path.GetDirectoryName(pathToExe); Directory.SetCurrentDirectory(pathToContentRootService); } else if (!Debugger.IsAttached && !justRun) { TerminalUI.Init(); return; } else { loggerConfig.WriteTo.Console(); } Log.Logger = loggerConfig.CreateLogger(); var pathToContentRoot = Directory.GetCurrentDirectory(); if (Debugger.IsAttached) { // var pathToExe = Process.GetCurrentProcess().MainModule.FileName; // pathToContentRoot = Path.GetDirectoryName(pathToExe); } else { // now relying on serilog // OverrideStdout(); } AppDomain.CurrentDomain.UnhandledException += (sender, e) => { var isTerminating = e.IsTerminating; Log.Fatal("Unhandled exception", e.ExceptionObject); ExceptionLogger.LogException(e.ExceptionObject as Exception); }; AppConfigSettings appConfigSettings = null; try { var appSettingsJson = File.ReadAllText("./appsettings.json"); appConfigSettings = System.Text.Json.JsonSerializer.Deserialize <AppConfigSettings>(appSettingsJson); } catch (Exception ex) { Log.Error(ex, "Failed to read appsettings.json"); } _startDate = DateTime.Now; var _ = UptimeLogger.LogServerUptimeAsync(); Log.Information($"Application started with process id {System.Diagnostics.Process.GetCurrentProcess().Id}."); // I forget what the different msg types look like Log.Warning("This is what a warning looks like"); Log.Error("This is what an error looks like"); Log.Fatal("This is what a fatal error looks like"); Log.Information("Loading users"); UserManagement.LoadUsersFromFile(); Log.Information("Initialising exception logger"); ExceptionLogger.Instance.Init(); Log.Information("Loading settings"); SettingsInstance.LoadSettingsFromFile(); Log.Information("Initialising real-time tracker"); RealtimeTrackerThread.Instance.Init(); if (appConfigSettings?.AppSettings?.Startup?.HealthMonitor ?? false) { Log.Information("Initialising jsDAL health monitor"); jsDALHealthMonitorThread.Instance.Init(); } else { Log.Information("jsDAL health monitor not configured to run at startup"); } if (appConfigSettings?.AppSettings?.Startup?.DataCollector ?? false) { Log.Information("Initialising data collector"); DataCollectorThread.Instance.Init(); } else { Log.Information("Data collector not configured to run at startup"); } Log.Information("Initialising inline module manifest"); InlineModuleManifest.Instance.Init(); Log.Information("Configuring global culture"); var globalCulture = new System.Globalization.CultureInfo("en-US"); // set global culture to en-US - will help with things like parsing numbers from Javascript(e.g. 10.123) as double/decimal even if server uses a comma as decimal separator for example CultureInfo.DefaultThreadCurrentCulture = globalCulture; CultureInfo.DefaultThreadCurrentUICulture = globalCulture; Log.Information("Building web host"); var builder = BuildWebHost(pathToContentRoot, args); var host = builder.Build(); if (isService) { host.RunAsCustomService(); } else { host.RunAsync(); Console.WriteLine("\r\nPress CTRL+X to shutdown server"); while (true) { var keyInfo = Console.ReadKey(true); if (keyInfo.Key == ConsoleKey.X && (keyInfo.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control) { //host.StopAsync(); ShutdownAllBackgroundThreads(); break; } } } } catch (Exception ex) { Log.Fatal(ex, "Application terminated unexpectedly"); SessionLog.Exception(ex); ShutdownAllBackgroundThreads(); } finally { Log.CloseAndFlush(); } }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IHostApplicationLifetime applicationLifetime) { //app.UseDeveloperExceptionPage(); // force instantiation on singletons { var pmInst = app.ApplicationServices.GetService <PluginLoader>(); CommonNotificationThread.Instance = app.ApplicationServices.GetService <CommonNotificationThread>(); BackgroundThreadPluginManager.Instance = app.ApplicationServices.GetService <BackgroundThreadPluginManager>(); WorkerMonitor.Instance = app.ApplicationServices.GetService <WorkerMonitor>(); RealtimeMonitor.Instance = app.ApplicationServices.GetService <RealtimeMonitor>(); BackgroundTaskMonitor.Instance = app.ApplicationServices.GetService <BackgroundTaskMonitor>(); ConnectionStringSecurity.Instance = app.ApplicationServices.GetService <ConnectionStringSecurity>(); DotNetCoreCounterListener.Instance = app.ApplicationServices.GetService <DotNetCoreCounterListener>(); DotNetCoreCounterListener.Instance.Start(); {// More app startup stuff...but have a dependency on the singleton objects above. Can we move this somewhere else? Log.Information("Initialising project object model"); // we can only initialise the Project structure once ConnectionStringSecurity exists Settings.SettingsInstance.Instance.ProjectList.ForEach(p => p.AfterDeserializationInit()); Log.Information("Initialising plugin loader"); PluginLoader.Instance = pmInst; PluginLoader.Instance.InitAsync().GetAwaiter().GetResult(); ServerMethodManager.RebuildCacheForAllApps(); Log.Information("Starting work spawner."); WorkSpawner.Start(); } } applicationLifetime.ApplicationStopped.Register(() => { Log.Information("Application stopped"); }); applicationLifetime.ApplicationStopping.Register(() => { Log.Information("Application is shutting down"); }); // app.Use(async (httpContext, next) => // { // //if (httpContext.Request.Path.Value.Contains("api/") && httpContext.Request.Method == "OPTIONS") // if (httpContext.Request.Method.Equals("OPTIONS", StringComparison.OrdinalIgnoreCase)) // { // httpContext.Response.Headers.Add("Access-Control-Max-Age", "600"); // // return; // } // await next(); // }); var webSocketOptions = new WebSocketOptions() { KeepAliveInterval = TimeSpan.FromSeconds(120), ReceiveBufferSize = 4 * 1024, }; app.UseWebSockets(webSocketOptions); app.UseCors("CorsPolicy"); // SPA (angular) route fallback app.Use(async(context, next) => { await next(); if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !(context.Request.Path.Value?.ToLower().StartsWith("/api/") ?? false)) { context.Request.Path = "/index.html"; context.Response.StatusCode = 200; await next(); } }); /***** * var mirrorSharpOptions = new MirrorSharpOptions() * { * SelfDebugEnabled = true, * IncludeExceptionDetails = true, * //SetOptionsFromClient = SetOptionsFromClientExtension() * // CSharp = { * // MetadataReferences = ImmutableList.Create<MetadataReference>(all), * // CompilationOptions = compilationOptions * // }, * ExceptionLogger = new MirrorSharpExceptionLogger() * }.SetupCSharp(cs => * { * //cs.MetadataReferences = cs.MetadataReferences.Clear(); * //cs.AddMetadataReferencesFromFiles(all); * cs.MetadataReferences = ImmutableList.Create<MetadataReference>(all); * cs.CompilationOptions = compilationOptions; * * }); * * * app.UseMirrorSharp(mirrorSharpOptions); */ app.UseDefaultFiles(); app.UseStaticFiles(); // TODO: This outputs full request detail into log. Perhaps consider outputting this to a different detailed log //app.UseSerilogRequestLogging(); app.UseSerilogRequestLogging(options => { options.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); // Customize the message template //HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms options.MessageTemplate = "Req/Res: {ReqLen,7} {ResLen,7} {StatusCode} {Elapsed,7:0} ms {RequestMethod,4} {RequestPath}"; //options.GetLevel = (httpContext, elapsed, ex) => Serilog.Events.LogEventLevel.Warning; // Attach additional properties to the request completion event options.EnrichDiagnosticContext = (diagnosticContext, httpContext) => { diagnosticContext.Set("ResLen", httpContext.Response.ContentLength ?? 0); diagnosticContext.Set("ReqLen", httpContext.Request.ContentLength ?? 0); }; }); app.UseRouting(); MetadataReference[] allMetadataReferences = null; try { allMetadataReferences = CSharpCompilerHelper.GetCommonMetadataReferences(); var jsDALBasePluginPath = Path.GetFullPath("./plugins/jsdal-plugin.dll"); if (File.Exists("./plugins/jsdal-plugin.dll")) { Array.Resize(ref allMetadataReferences, allMetadataReferences.Length + 1); allMetadataReferences[allMetadataReferences.Length - 1] = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(jsDALBasePluginPath); } else { Log.Error($"Failed to find base plugin assembly at {jsDALBasePluginPath}"); SessionLog.Error($"Failed to find base plugin assembly at {jsDALBasePluginPath}"); } } catch (Exception mex) { Log.Error(mex, "Failed to compile collection of metadata references"); } app.UseEndpoints(endpoints => { endpoints.MapHub <Hubs.HomeDashboardHub>("/main-stats"); endpoints.MapHub <Hubs.WorkerDashboardHub>("/worker-hub"); endpoints.MapHub <Hubs.Performance.RealtimeHub>("/performance-realtime-hub"); endpoints.MapHub <Hubs.HeartBeat.HeartBeatHub>("/heartbeat"); endpoints.MapHub <Hubs.BackgroundTaskHub>("/bgtasks-hub"); endpoints.MapHub <Hubs.BackgroundPluginHub>("/bgplugin-hub"); endpoints.MapHub <Hubs.ExecHub>("/exec-hub"); if (allMetadataReferences?.Length > 0) { var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, // generalDiagnosticOption: ReportDiagnostic.Suppress specificDiagnosticOptions: new Dictionary <string, ReportDiagnostic> { { "CS1701", ReportDiagnostic.Suppress }, // Binding redirects { "CS1702", ReportDiagnostic.Suppress }, { "CS1705", ReportDiagnostic.Suppress } } ); var mirrorSharpOptions = new MirrorSharpOptions() { SelfDebugEnabled = true, IncludeExceptionDetails = true //SetOptionsFromClient = SetOptionsFromClientExtension() // CSharp = { // MetadataReferences = ImmutableList.Create<MetadataReference>(all), // CompilationOptions = compilationOptions // }, // ExceptionLogger = new MirrorSharpExceptionLogger() }.SetupCSharp(cs => { //cs.MetadataReferences = cs.MetadataReferences.Clear(); //cs.AddMetadataReferencesFromFiles(all); cs.MetadataReferences = ImmutableList.Create <MetadataReference>(allMetadataReferences); cs.CompilationOptions = compilationOptions; }); endpoints.MapMirrorSharp("/mirrorsharp", mirrorSharpOptions); } else { Log.Warning("Mirrorsharp not started because of errors builiding up metadata references"); } }); app.UseAuthentication(); app.UseWebSockets(); app.UseCookiePolicy(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); // unhandled exceptions app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { try { var exceptionHandlerPathFeature = context.Features.Get <IExceptionHandlerPathFeature>(); var id = ExceptionLogger.LogException(exceptionHandlerPathFeature.Error, exceptionHandlerPathFeature.Path, "jsdal-server", null); context.Response.StatusCode = 500; context.Response.ContentType = "text/plain"; await context.Response.WriteAsync($"Server error. Ref: {id}"); await context.Response.WriteAsync(new string(' ', 512)); // IE padding } catch (Exception ex) { Log.Error(ex, $"Failed to log unhandled exception because of:\r\n {ex.ToString()}"); } }); }); } app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }