├── .gitignore ├── LICENSE ├── README.md └── jsnlogSimpleWorkingDemos ├── NetCore ├── JSNLogDemo_Core_DefaultAjaxUrl │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_DefaultAjaxUrl.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_LoggingEventHandlers │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_LoggingEventHandlers.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_Net4x │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_Net4x.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ ├── js │ │ └── jsnlogdemo.js │ │ └── lib │ │ └── jsnlog │ │ └── jsnlog.js ├── JSNLogDemo_Core_Net5 │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_Net5.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_Net6 │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_Net6.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_Net7 │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_Net7.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_Net7_CORS │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_Net7_CORS.csproj │ ├── Program.cs │ ├── Properties │ │ ├── PublishProfiles │ │ │ └── FolderProfile.pubxml │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_Net7_beforeSend │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_Net7_beforeSend.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js ├── JSNLogDemo_Core_NetCoreApp2 │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_NetCoreApp2.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ ├── js │ │ └── jsnlogdemo.js │ │ └── lib │ │ └── jsnlog │ │ └── jsnlog.js ├── JSNLogDemo_Core_NetCoreApp3 │ ├── Controllers │ │ └── HomeController.cs │ ├── JSNLogDemo_Core_NetCoreApp3.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── Error.cshtml │ │ └── _ViewImports.cshtml │ └── wwwroot │ │ ├── favicon.ico │ │ └── js │ │ └── jsnlogdemo.js └── JSNLogDemo_NLog_NetCoreRequestId │ ├── Controllers │ └── HomeController.cs │ ├── JSNLogDemo_NLog_NetCoreRequestId.csproj │ ├── NLog.config │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ └── Error.cshtml │ └── _ViewImports.cshtml │ ├── appsettings.json │ └── wwwroot │ ├── favicon.ico │ ├── js │ └── jsnlogdemo.js │ └── lib │ └── jsnlog │ └── jsnlog.js └── jsnlogSimpleWorkingDemos.sln /.gitignore: -------------------------------------------------------------------------------- 1 | packages/ 2 | 3 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 4 | [Bb]in/ 5 | [Oo]bj/ 6 | 7 | # mstest test results 8 | TestResults 9 | 10 | ## Ignore Visual Studio temporary files, build results, and 11 | ## files generated by popular Visual Studio add-ons. 12 | 13 | # User-specific files 14 | *.suo 15 | *.user 16 | *.sln.docstates 17 | .vs/ 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Rr]elease/ 22 | x64/ 23 | *_i.c 24 | *_p.c 25 | *.ilk 26 | *.meta 27 | *.obj 28 | *.pch 29 | *.pdb 30 | *.pgc 31 | *.pgd 32 | *.rsp 33 | *.sbr 34 | *.tlb 35 | *.tli 36 | *.tlh 37 | *.tmp 38 | *.log 39 | *.vspscc 40 | *.vssscc 41 | .builds 42 | 43 | # Visual C++ cache files 44 | ipch/ 45 | *.aps 46 | *.ncb 47 | *.opensdf 48 | *.sdf 49 | 50 | # Visual Studio profiler 51 | *.psess 52 | *.vsp 53 | *.vspx 54 | 55 | # Guidance Automation Toolkit 56 | *.gpState 57 | 58 | # ReSharper is a .NET coding add-in 59 | _ReSharper* 60 | 61 | # NCrunch 62 | *.ncrunch* 63 | .*crunch*.local.xml 64 | 65 | # Installshield output folder 66 | [Ee]xpress 67 | 68 | # DocProject is a documentation generator add-in 69 | DocProject/buildhelp/ 70 | DocProject/Help/*.HxT 71 | DocProject/Help/*.HxC 72 | DocProject/Help/*.hhc 73 | DocProject/Help/*.hhk 74 | DocProject/Help/*.hhp 75 | DocProject/Help/Html2 76 | DocProject/Help/html 77 | 78 | # Click-Once directory 79 | publish 80 | 81 | # Publish Web Output 82 | *.Publish.xml 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | # [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | UpgradeLog*.htm 110 | 111 | Logs/ 112 | !EmptyWebFormsWebsite/Bin/ 113 | !EmptyWebFormsWebsite - Log4Net/Bin/ 114 | !EmptyWebFormsWebsite/Bin/*.dll 115 | !EmptyWebFormsWebsite - Log4Net/Bin/*.dll 116 | 117 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012-2015 Mattijs Perdeck 2 | 3 | This project is licensed under the MIT license. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Download this repo and open the solution in Visual Studio. 2 | 3 | You will find simple well documented web projects that use JSNLog to send log messages from client side JavaScript code to the server side log. 4 | 5 | To run a project: 6 | 1. Right click the project | Set as Startup Project 7 | 2. F5 8 | 9 | The home page of the demo site will be loaded into your browser. That will give you more information. 10 | 11 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_DefaultAjaxUrl.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/JSNLogDemo_Core_DefaultAjaxUrl.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_DefaultAjaxUrl 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9010/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9010/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_DefaultAjaxUrl 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | 49 | // Configure JSNLog 50 | // Do this before calling UseStaticFiles. 51 | // 52 | // This configuration tells jsnlog.js to send log entries to /logging/mylogger.html 53 | // It tells the server side library JSNLog to regard all requests to /logging/mylogger.html as log entries. 54 | // 55 | // Setting insertJsnlogInHtmlResponses to true ensures that the client side code for JSNLog will 56 | // be inserted in the html responses to the browser, so you don't have to deal with this. 57 | // 58 | // For configuration options, see 59 | // https://jsnlog.com/Documentation/Configuration 60 | app.UseJSNLog(loggerFactory, new JsnlogConfiguration() 61 | { 62 | insertJsnlogInHtmlResponses = true, 63 | productionLibraryPath = "https://cdnjs.cloudflare.com/ajax/libs/jsnlog/2.30.0/jsnlog.min.js", 64 | defaultAjaxUrl = "/logging/mylogger.html" 65 | }) ; 66 | 67 | 68 | 69 | 70 | app.UseStaticFiles(); 71 | 72 | app.UseRouting(); 73 | 74 | app.UseAuthorization(); 75 | 76 | app.UseEndpoints(endpoints => 77 | { 78 | endpoints.MapControllerRoute( 79 | name: "default", 80 | pattern: "{controller=Home}/{action=Index}/{id?}"); 81 | }); 82 | } 83 | } 84 | } 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_DefaultAjaxUrl

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_DefaultAjaxUrl/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_LoggingEventHandlers.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/JSNLogDemo_Core_LoggingEventHandlers.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_LoggingEventHandlers 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9009/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9009/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | using System.Linq; 10 | using System.Collections.Generic; 11 | 12 | 13 | namespace JSNLogDemo_Core_LoggingEventHandlers 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | public void ConfigureServices(IServiceCollection services) 26 | { 27 | services.AddRazorPages(); 28 | } 29 | 30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 31 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 32 | { 33 | 34 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 35 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 36 | // 37 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 38 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 39 | 40 | 41 | if (env.IsDevelopment()) 42 | { 43 | app.UseDeveloperExceptionPage(); 44 | } 45 | else 46 | { 47 | app.UseExceptionHandler("/Error"); 48 | } 49 | 50 | 51 | // Configure JSNLog 52 | // Do this before calling UseStaticFiles. 53 | // 54 | // For configuration options, see 55 | // https://jsnlog.com/Documentation/Configuration 56 | app.UseJSNLog(loggerFactory); 57 | 58 | 59 | 60 | 61 | // Add logging handler to JSNLog that: 62 | // 1) suppresses all messages containing the string "this will be suppressed" 63 | // 2) adds all request headers to the remaining messages 64 | 65 | // Create logging event handler 66 | LoggingHandler loggingHandler = (LoggingEventArgs loggingEventArgs) => 67 | { 68 | if (loggingEventArgs.FinalMessage.Contains("this will be suppressed")) 69 | { 70 | // Tell JSNLog not to log this message 71 | loggingEventArgs.Cancel = true; 72 | return; 73 | } 74 | 75 | Dictionary logRequestHeaders = loggingEventArgs.LogRequest.Headers; 76 | string logRequestHeadersString = 77 | string.Join(" | ", logRequestHeaders.Select(m => m.Key + ":" + m.Value).ToArray()); 78 | 79 | // Add string with headers to the log message that will be sent to the logging package 80 | loggingEventArgs.FinalMessage += " >> Request Headers >> " + logRequestHeadersString; 81 | }; 82 | 83 | // Add the new handler to the logging event, so it will be called when a log message is 84 | // about to be sent to the server side logging package. 85 | JavascriptLogging.OnLogging += loggingHandler; 86 | 87 | 88 | app.UseStaticFiles(); 89 | 90 | app.UseRouting(); 91 | 92 | app.UseAuthorization(); 93 | 94 | app.UseEndpoints(endpoints => 95 | { 96 | endpoints.MapControllerRoute( 97 | name: "default", 98 | pattern: "{controller=Home}/{action=Index}/{id?}"); 99 | }); 100 | } 101 | } 102 | } 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_LoggingEventHandlers

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_LoggingEventHandlers/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | JL("jsLogger").fatal("fatal client log message - this will be suppressed by logging event handler"); 7 | 8 | 9 | // Log with every severity 10 | JL("jsLogger").debug("debug client log message"); 11 | JL("jsLogger").info("info client log message"); 12 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 13 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 14 | JL("jsLogger").fatal("fatal client log message"); 15 | 16 | // Log caught exception 17 | try { 18 | // ReferenceError: xyz is not defined 19 | xyz; 20 | } catch (e) { 21 | // Log the exception 22 | JL().fatalException("Something went wrong!", e); 23 | } 24 | 25 | // ReferenceError: xyz2 is not defined. 26 | xyz2; 27 | }); 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_Net4x.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/JSNLogDemo_Core_Net4x.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net47 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace JSNLogDemo_Core_Net4x 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9006/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9006/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | using JSNLog; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace JSNLogDemo_Core_Net4x 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | public void ConfigureServices(IServiceCollection services) 26 | { 27 | services.AddMvc(); 28 | } 29 | 30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 31 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 32 | { 33 | 34 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 35 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 36 | // 37 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 38 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 39 | 40 | 41 | if (env.IsDevelopment()) 42 | { 43 | app.UseDeveloperExceptionPage(); 44 | app.UseBrowserLink(); 45 | } 46 | else 47 | { 48 | app.UseExceptionHandler("/Home/Error"); 49 | } 50 | 51 | 52 | // Configure JSNLog 53 | // Do this before calling UseStaticFiles. 54 | // 55 | // For configuration options, see 56 | // https://jsnlog.com/Documentation/Configuration 57 | app.UseJSNLog(loggerFactory, new JsnlogConfiguration()); 58 | 59 | 60 | app.UseStaticFiles(); 61 | 62 | app.UseMvc(routes => 63 | { 64 | routes.MapRoute( 65 | name: "default", 66 | template: "{controller=Home}/{action=Index}/{id?}"); 67 | }); 68 | } 69 | } 70 | } 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_Net4x

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net4x/wwwroot/lib/jsnlog/jsnlog.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JSNLog 2.30.0 3 | * Open source under the MIT License. 4 | * Copyright 2012-2024 Mattijs Perdeck All rights reserved. 5 | */ 6 | var __extends = (this && this.__extends) || (function () { 7 | var extendStatics = function (d, b) { 8 | extendStatics = Object.setPrototypeOf || 9 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 10 | function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 11 | return extendStatics(d, b); 12 | }; 13 | return function (d, b) { 14 | extendStatics(d, b); 15 | function __() { this.constructor = d; } 16 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 17 | }; 18 | })(); 19 | function JL(loggerName) { 20 | // If name is empty, return the root logger 21 | if (!loggerName) { 22 | return JL.__; 23 | } 24 | // Implements Array.reduce. JSNLog supports IE8+ and reduce is not supported in that browser. 25 | // Same interface as the standard reduce, except that 26 | if (!Array.prototype.reduce) { 27 | Array.prototype.reduce = function (callback, initialValue) { 28 | var previousValue = initialValue; 29 | for (var i = 0; i < this.length; i++) { 30 | previousValue = callback(previousValue, this[i], i, this); 31 | } 32 | return previousValue; 33 | }; 34 | } 35 | var accumulatedLoggerName = ''; 36 | var logger = ('.' + loggerName).split('.').reduce(function (prev, curr, idx, arr) { 37 | // if loggername is a.b.c, than currentLogger will be set to the loggers 38 | // root (prev: JL, curr: '') 39 | // a (prev: JL.__, curr: 'a') 40 | // a.b (prev: JL.__.__a, curr: 'b') 41 | // a.b.c (prev: JL.__.__a.__a.b, curr: 'c') 42 | // Note that when a new logger name is encountered (such as 'a.b.c'), 43 | // a new logger object is created and added as a property to the parent ('a.b'). 44 | // The root logger is added as a property of the JL object itself. 45 | // It is essential that the name of the property containing the child logger 46 | // contains the full 'path' name of the child logger ('a.b.c') instead of 47 | // just the bit after the last period ('c'). 48 | // This is because the parent inherits properties from its ancestors. 49 | // So if the root has a child logger 'c' (stored in a property 'c' of the root logger), 50 | // then logger 'a.b' has that same property 'c' through inheritance. 51 | // The names of the logger properties start with __, so the root logger 52 | // (which has name ''), has a nice property name '__'. 53 | // accumulatedLoggerName evaluates false ('' is falsy) in first iteration when prev is the root logger. 54 | // accumulatedLoggerName will be the logger name corresponding with the logger in currentLogger. 55 | // Keep in mind that the currentLogger may not be defined yet, so can't get the name from 56 | // the currentLogger object itself. 57 | if (accumulatedLoggerName) { 58 | accumulatedLoggerName += '.' + curr; 59 | } 60 | else { 61 | accumulatedLoggerName = curr; 62 | } 63 | var currentLogger = prev['__' + accumulatedLoggerName]; 64 | // If the currentLogger (or the actual logger being sought) does not yet exist, 65 | // create it now. 66 | if (currentLogger === undefined) { 67 | // Set the prototype of the Logger constructor function to the parent of the logger 68 | // to be created. This way, __proto of the new logger object will point at the parent. 69 | // When logger.level is evaluated and is not present, the JavaScript runtime will 70 | // walk down the prototype chain to find the first ancestor with a level property. 71 | // 72 | // Note that prev at this point refers to the parent logger. 73 | JL.Logger.prototype = prev; 74 | currentLogger = new JL.Logger(accumulatedLoggerName); 75 | prev['__' + accumulatedLoggerName] = currentLogger; 76 | } 77 | return currentLogger; 78 | }, JL.__); 79 | return logger; 80 | } 81 | (function (JL) { 82 | // Initialise requestId to empty string. If you don't do this and the user 83 | // does not set it via setOptions, then the JSNLog-RequestId header will 84 | // have value "undefined", which doesn't look good in a log. 85 | // 86 | // Note that you always want to send a requestId as part of log requests, 87 | // otherwise the server side component doesn't know this is a log request 88 | // and may create a new request id for the log request, causing confusion 89 | // in the log. 90 | JL.requestId = ''; 91 | // Number uniquely identifying every log entry within the request. 92 | JL.entryId = 0; 93 | // Allow property injection of these classes, to enable unit testing 94 | JL._createXMLHttpRequest = function () { return new XMLHttpRequest(); }; 95 | JL._getTime = function () { return (new Date).getTime(); }; 96 | JL._console = console; 97 | // ----- private variables 98 | JL._appenderNames = []; 99 | /** 100 | Copies the value of a property from one object to the other. 101 | This is used to copy property values as part of setOption for loggers and appenders. 102 | 103 | Because loggers inherit property values from their parents, it is important never to 104 | create a property on a logger if the intent is to inherit from the parent. 105 | 106 | Copying rules: 107 | 1) if the from property is undefined (for example, not mentioned in a JSON object), the 108 | to property is not affected at all. 109 | 2) if the from property is null, the to property is deleted (so the logger will inherit from 110 | its parent). 111 | 3) Otherwise, the from property is copied to the to property. 112 | */ 113 | function copyProperty(propertyName, from, to) { 114 | if (from[propertyName] === undefined) { 115 | return; 116 | } 117 | if (from[propertyName] === null) { 118 | delete to[propertyName]; 119 | return; 120 | } 121 | to[propertyName] = from[propertyName]; 122 | } 123 | /** 124 | Returns true if a log should go ahead. 125 | Does not check level. 126 | 127 | @param filters 128 | Filters that determine whether a log can go ahead. 129 | */ 130 | function allow(filters) { 131 | // If enabled is not null or undefined, then if it is false, then return false 132 | // Note that undefined==null (!) 133 | if (!(JL.enabled == null)) { 134 | if (!JL.enabled) { 135 | return false; 136 | } 137 | } 138 | // If the regex contains a bug, that will throw an exception. 139 | // Ignore this, and pass the log item (better too much than too little). 140 | try { 141 | if (filters.userAgentRegex) { 142 | if (!new RegExp(filters.userAgentRegex).test(navigator.userAgent)) { 143 | return false; 144 | } 145 | } 146 | } 147 | catch (e) { } 148 | try { 149 | if (filters.ipRegex && JL.clientIP) { 150 | if (!new RegExp(filters.ipRegex).test(JL.clientIP)) { 151 | return false; 152 | } 153 | } 154 | } 155 | catch (e) { } 156 | return true; 157 | } 158 | /** 159 | Returns true if a log should go ahead, based on the message. 160 | 161 | @param filters 162 | Filters that determine whether a log can go ahead. 163 | 164 | @param message 165 | Message to be logged. 166 | */ 167 | function allowMessage(filters, message) { 168 | // If the regex contains a bug, that will throw an exception. 169 | // Ignore this, and pass the log item (better too much than too little). 170 | try { 171 | if (filters.disallow) { 172 | if (new RegExp(filters.disallow).test(message)) { 173 | return false; 174 | } 175 | } 176 | } 177 | catch (e) { } 178 | return true; 179 | } 180 | // If logObject is a function, the function is evaluated (without parameters) 181 | // and the result returned. 182 | // Otherwise, logObject itself is returned. 183 | function stringifyLogObjectFunction(logObject) { 184 | if (typeof logObject == "function") { 185 | if (logObject instanceof RegExp) { 186 | return logObject.toString(); 187 | } 188 | else { 189 | return logObject(); 190 | } 191 | } 192 | return logObject; 193 | } 194 | var StringifiedLogObject = /** @class */ (function () { 195 | // * msg - 196 | // if the logObject is a scalar (after possible function evaluation), this is set to 197 | // string representing the scalar. Otherwise it is left undefined. 198 | // * meta - 199 | // if the logObject is an object (after possible function evaluation), this is set to 200 | // that object. Otherwise it is left undefined. 201 | // * finalString - 202 | // This is set to the string representation of logObject (after possible function evaluation), 203 | // regardless of whether it is an scalar or an object. An object is stringified to a JSON string. 204 | // Note that you can't call this field "final", because as some point this was a reserved 205 | // JavaScript keyword and using final trips up some minifiers. 206 | function StringifiedLogObject(msg, meta, finalString) { 207 | this.msg = msg; 208 | this.meta = meta; 209 | this.finalString = finalString; 210 | } 211 | return StringifiedLogObject; 212 | }()); 213 | // Takes a logObject, which can be 214 | // * a scalar 215 | // * an object 216 | // * a parameterless function, which returns the scalar or object to log. 217 | // Returns a stringifiedLogObject 218 | function stringifyLogObject(logObject) { 219 | // Note that this works if logObject is null. 220 | // typeof null is object. 221 | // JSON.stringify(null) returns "null". 222 | var actualLogObject = stringifyLogObjectFunction(logObject); 223 | var finalString; 224 | // Note that typeof actualLogObject should not be "function", because that has 225 | // been resolved with stringifyLogObjectFunction. 226 | switch (typeof actualLogObject) { 227 | case "string": 228 | return new StringifiedLogObject(actualLogObject, null, actualLogObject); 229 | case "number": 230 | finalString = actualLogObject.toString(); 231 | return new StringifiedLogObject(finalString, null, finalString); 232 | case "boolean": 233 | finalString = actualLogObject.toString(); 234 | return new StringifiedLogObject(finalString, null, finalString); 235 | case "undefined": 236 | return new StringifiedLogObject("undefined", null, "undefined"); 237 | case "object": 238 | if ((actualLogObject instanceof RegExp) || 239 | (actualLogObject instanceof String) || 240 | (actualLogObject instanceof Number) || 241 | (actualLogObject instanceof Boolean)) { 242 | finalString = actualLogObject.toString(); 243 | return new StringifiedLogObject(finalString, null, finalString); 244 | } 245 | else { 246 | if (typeof JL.serialize === 'function') { 247 | finalString = JL.serialize.call(this, actualLogObject); 248 | } 249 | else { 250 | finalString = JSON.stringify(actualLogObject); 251 | } 252 | // Set the msg field to "" instead of null. Some Winston transports 253 | // assume that the msg field is not null. 254 | return new StringifiedLogObject("", actualLogObject, finalString); 255 | } 256 | default: 257 | return new StringifiedLogObject("unknown", null, "unknown"); 258 | } 259 | } 260 | function setOptions(options) { 261 | copyProperty("enabled", options, this); 262 | copyProperty("maxMessages", options, this); 263 | copyProperty("defaultAjaxUrl", options, this); 264 | copyProperty("clientIP", options, this); 265 | copyProperty("requestId", options, this); 266 | copyProperty("defaultBeforeSend", options, this); 267 | copyProperty("serialize", options, this); 268 | return this; 269 | } 270 | JL.setOptions = setOptions; 271 | function getAllLevel() { return -2147483648; } 272 | JL.getAllLevel = getAllLevel; 273 | function getTraceLevel() { return 1000; } 274 | JL.getTraceLevel = getTraceLevel; 275 | function getDebugLevel() { return 2000; } 276 | JL.getDebugLevel = getDebugLevel; 277 | function getInfoLevel() { return 3000; } 278 | JL.getInfoLevel = getInfoLevel; 279 | function getWarnLevel() { return 4000; } 280 | JL.getWarnLevel = getWarnLevel; 281 | function getErrorLevel() { return 5000; } 282 | JL.getErrorLevel = getErrorLevel; 283 | function getFatalLevel() { return 6000; } 284 | JL.getFatalLevel = getFatalLevel; 285 | function getOffLevel() { return 2147483647; } 286 | JL.getOffLevel = getOffLevel; 287 | function levelToString(level) { 288 | if (level <= 1000) { 289 | return "trace"; 290 | } 291 | if (level <= 2000) { 292 | return "debug"; 293 | } 294 | if (level <= 3000) { 295 | return "info"; 296 | } 297 | if (level <= 4000) { 298 | return "warn"; 299 | } 300 | if (level <= 5000) { 301 | return "error"; 302 | } 303 | return "fatal"; 304 | } 305 | // --------------------- 306 | var Exception = /** @class */ (function () { 307 | // data replaces message. It takes not just strings, but also objects and functions, just like the log function. 308 | // internally, the string representation is stored in the message property (inherited from Error) 309 | // 310 | // inner: inner exception. Can be null or undefined. 311 | function Exception(data, inner) { 312 | this.inner = inner; 313 | this.name = "JL.Exception"; 314 | this.message = stringifyLogObject(data).finalString; 315 | } 316 | return Exception; 317 | }()); 318 | JL.Exception = Exception; 319 | // Derive Exception from Error (a Host object), so browsers 320 | // are more likely to produce a stack trace for it in their console. 321 | // 322 | // Note that instanceof against an object created with this constructor 323 | // will return true in these cases: 324 | // instanceof JL.Exception); 325 | // instanceof Error); 326 | Exception.prototype = new Error(); 327 | // --------------------- 328 | var LogItem = /** @class */ (function () { 329 | // l: level 330 | // m: message 331 | // n: logger name 332 | // t (timeStamp) is number of milliseconds since 1 January 1970 00:00:00 UTC 333 | // u: number uniquely identifying this entry for this request. 334 | // 335 | // Keeping the property names really short, because they will be sent in the 336 | // JSON payload to the server. 337 | function LogItem(l, m, n, t, u) { 338 | this.l = l; 339 | this.m = m; 340 | this.n = n; 341 | this.t = t; 342 | this.u = u; 343 | } 344 | return LogItem; 345 | }()); 346 | JL.LogItem = LogItem; 347 | function newLogItem(levelNbr, message, loggerName) { 348 | JL.entryId++; 349 | return new LogItem(levelNbr, message, loggerName, JL._getTime(), JL.entryId); 350 | } 351 | function clearTimer(timer) { 352 | if (timer.id) { 353 | clearTimeout(timer.id); 354 | timer.id = null; 355 | } 356 | } 357 | function setTimer(timer, timeoutMs, callback) { 358 | var that = this; 359 | if (!timer.id) { 360 | timer.id = setTimeout(function () { 361 | // use call to ensure that the this as used inside sendBatch when it runs is the 362 | // same this at this point. 363 | callback.call(that); 364 | }, timeoutMs); 365 | } 366 | } 367 | var Appender = /** @class */ (function () { 368 | // sendLogItems takes an array of log items. It will be called when 369 | // the appender has items to process (such as, send to the server). 370 | // sendLogItems will call successCallback after the items have been successfully sent. 371 | // 372 | // Note that after sendLogItems returns, the appender may truncate 373 | // the LogItem array, so the function has to copy the content of the array 374 | // in some fashion (eg. serialize) before returning. 375 | function Appender(appenderName, sendLogItems) { 376 | this.appenderName = appenderName; 377 | this.sendLogItems = sendLogItems; 378 | this.level = JL.getTraceLevel(); 379 | // set to super high level, so if user increases level, level is unlikely to get 380 | // above sendWithBufferLevel 381 | this.sendWithBufferLevel = 2147483647; 382 | this.storeInBufferLevel = -2147483648; 383 | this.bufferSize = 0; // buffering switch off by default 384 | this.batchSize = 1; 385 | this.maxBatchSize = 20; 386 | this.batchTimeout = 2147483647; 387 | this.sendTimeout = 5000; 388 | // Holds all log items with levels higher than storeInBufferLevel 389 | // but lower than level. These items may never be sent. 390 | this.buffer = []; 391 | // Holds all items that we do want to send, until we have a full 392 | // batch (as determined by batchSize). 393 | this.batchBuffer = []; 394 | // Holds the id of the timer implementing the batch timeout. 395 | // Can be null. 396 | // This is an object, so it can be passed to a method that updated the timer variable. 397 | this.batchTimeoutTimer = { id: null }; 398 | // Holds the id of the timer implementing the send timeout. 399 | // Can be null. 400 | this.sendTimeoutTimer = { id: null }; 401 | // Number of log items that has been skipped due to batch buffer at max size, 402 | // since appender creation or since creation of the last "skipped" warning log entry. 403 | this.nbrLogItemsSkipped = 0; 404 | // Will be 0 if no log request is outstanding at the moment. 405 | // Otherwise the number of log items in the outstanding request. 406 | this.nbrLogItemsBeingSent = 0; 407 | var emptyNameErrorMessage = "Trying to create an appender without a name or with an empty name"; 408 | // This evaluates to true if appenderName is either null or undefined! 409 | // Do not check here if the name is "", because that would stop you creating the 410 | // default appender. 411 | if (appenderName == undefined) { 412 | throw emptyNameErrorMessage; 413 | } 414 | if (JL._appenderNames.indexOf(appenderName) != -1) { 415 | // If user passed in "", that will now have been picked up as a duplicate 416 | // because default appender also uses "". 417 | if (!appenderName) { 418 | throw emptyNameErrorMessage; 419 | } 420 | throw "Multiple appenders use the same name " + appenderName; 421 | } 422 | JL._appenderNames.push(appenderName); 423 | } 424 | Appender.prototype.addLogItemsToBuffer = function (logItems) { 425 | // If the batch buffer has reached its maximum limit, 426 | // skip the log item and increase the "skipped items" counter. 427 | if (this.batchBuffer.length >= this.maxBatchSize) { 428 | this.nbrLogItemsSkipped += logItems.length; 429 | return; 430 | } 431 | // If maxMessages is not null or undefined, then decrease it by the batch size. 432 | // This can result in a negative maxMessages. 433 | // Note that undefined==null (!) 434 | // 435 | // Note that we may be sending more messages than the maxMessages limit allows, 436 | // if we stored trace messages. Rationale is the buffer for trace messages is limited, 437 | // and if we cut off at exactly maxMessages, we'd also loose the high severity message 438 | // that caused the trace messages to be sent (unless we cater for this specifically, which 439 | // is more complexity). 440 | // 441 | // If there are multiple appenders sending the same message, maxMessage will be decreased 442 | // by each appender for the same message. This is: 443 | // 1) only appenders know whether a message will actually be sent (based on storeInBufferLevel), 444 | // so the loggers couldn't do this update; 445 | // 2) if you have multiple appenders hitting the same server, this may be what you want. 446 | // 447 | // In most cases there is only 1 appender, so this then doesn't matter. 448 | if (!(JL.maxMessages == null)) { 449 | if (JL.maxMessages < 1) { 450 | return; 451 | } 452 | JL.maxMessages -= logItems.length; 453 | } 454 | this.batchBuffer = this.batchBuffer.concat(logItems); 455 | // If this is the first item in the buffer, set the timer 456 | // to ensure it will be sent within the timeout period. 457 | // If it is not the first item, leave the timer alone so to not to 458 | // increase the timeout for the first item. 459 | // 460 | // To determine if this is the first item, look at the timer variable. 461 | // Do not look at the buffer length, because we also put items in the buffer 462 | // via a concat (bypassing this function). 463 | // 464 | // The setTimer method only sets the timer if it is not already running. 465 | var that = this; 466 | setTimer(this.batchTimeoutTimer, this.batchTimeout, function () { 467 | that.sendBatch.call(that); 468 | }); 469 | }; 470 | ; 471 | Appender.prototype.batchBufferHasOverdueMessages = function () { 472 | for (var i = 0; i < this.batchBuffer.length; i++) { 473 | var messageAgeMs = JL._getTime() - this.batchBuffer[i].t; 474 | if (messageAgeMs > this.batchTimeout) { 475 | return true; 476 | } 477 | } 478 | return false; 479 | }; 480 | // Returns true if no more message will ever be added to the batch buffer, 481 | // but the batch buffer has messages now - so if there are not enough to make up a batch, 482 | // and there is no batch timeout, then they will never be sent. This is especially important if 483 | // maxMessages was reached while jsnlog.js was retrying sending messages to the server. 484 | Appender.prototype.batchBufferHasStrandedMessage = function () { 485 | return (!(JL.maxMessages == null)) && (JL.maxMessages < 1) && (this.batchBuffer.length > 0); 486 | }; 487 | Appender.prototype.sendBatchIfComplete = function () { 488 | if ((this.batchBuffer.length >= this.batchSize) || 489 | this.batchBufferHasOverdueMessages() || 490 | this.batchBufferHasStrandedMessage()) { 491 | this.sendBatch(); 492 | } 493 | }; 494 | Appender.prototype.onSendingEnded = function () { 495 | clearTimer(this.sendTimeoutTimer); 496 | this.nbrLogItemsBeingSent = 0; 497 | this.sendBatchIfComplete(); 498 | }; 499 | Appender.prototype.setOptions = function (options) { 500 | copyProperty("level", options, this); 501 | copyProperty("ipRegex", options, this); 502 | copyProperty("userAgentRegex", options, this); 503 | copyProperty("disallow", options, this); 504 | copyProperty("sendWithBufferLevel", options, this); 505 | copyProperty("storeInBufferLevel", options, this); 506 | copyProperty("bufferSize", options, this); 507 | copyProperty("batchSize", options, this); 508 | copyProperty("maxBatchSize", options, this); 509 | copyProperty("batchTimeout", options, this); 510 | copyProperty("sendTimeout", options, this); 511 | if (this.bufferSize < this.buffer.length) { 512 | this.buffer.length = this.bufferSize; 513 | } 514 | if (this.maxBatchSize < this.batchSize) { 515 | throw new JL.Exception({ 516 | "message": "maxBatchSize cannot be smaller than batchSize", 517 | "maxBatchSize": this.maxBatchSize, 518 | "batchSize": this.batchSize 519 | }); 520 | } 521 | return this; 522 | }; 523 | /** 524 | Called by a logger to log a log item. 525 | If in response to this call one or more log items need to be processed 526 | (eg., sent to the server), this method calls this.sendLogItems 527 | with an array with all items to be processed. 528 | 529 | Note that the name and parameters of this function must match those of the log function of 530 | a Winston transport object, so that users can use these transports as appenders. 531 | That is why there are many parameters that are not actually used by this function. 532 | 533 | level - string with the level ("trace", "debug", etc.) Only used by Winston transports. 534 | msg - human readable message. Undefined if the log item is an object. Only used by Winston transports. 535 | meta - log object. Always defined, because at least it contains the logger name. Only used by Winston transports. 536 | callback - function that is called when the log item has been logged. Only used by Winston transports. 537 | levelNbr - level as a number. Not used by Winston transports. 538 | message - log item. If the user logged an object, this is the JSON string. Not used by Winston transports. 539 | loggerName: name of the logger. Not used by Winston transports. 540 | */ 541 | Appender.prototype.log = function (level, msg, meta, callback, levelNbr, message, loggerName) { 542 | var logItem; 543 | if (!allow(this)) { 544 | return; 545 | } 546 | if (!allowMessage(this, message)) { 547 | return; 548 | } 549 | if (levelNbr < this.storeInBufferLevel) { 550 | // Ignore the log item completely 551 | return; 552 | } 553 | logItem = newLogItem(levelNbr, message, loggerName); 554 | if (levelNbr < this.level) { 555 | // Store in the hold buffer. Do not send. 556 | if (this.bufferSize > 0) { 557 | this.buffer.push(logItem); 558 | // If we exceeded max buffer size, remove oldest item 559 | if (this.buffer.length > this.bufferSize) { 560 | this.buffer.shift(); 561 | } 562 | } 563 | return; 564 | } 565 | // Want to send the item 566 | this.addLogItemsToBuffer([logItem]); 567 | if (levelNbr >= this.sendWithBufferLevel) { 568 | // Want to send the contents of the buffer. 569 | // 570 | // Send the buffer AFTER sending the high priority item. 571 | // If you were to send the high priority item after the buffer, 572 | // if we're close to maxMessages or maxBatchSize, 573 | // then the trace messages in the buffer could crowd out the actual high priority item. 574 | if (this.buffer.length) { 575 | this.addLogItemsToBuffer(this.buffer); 576 | this.buffer.length = 0; 577 | } 578 | } 579 | this.sendBatchIfComplete(); 580 | }; 581 | ; 582 | // Processes the batch buffer 583 | // 584 | // Make this public, so it can be called from outside the library, 585 | // when the page is unloaded. 586 | Appender.prototype.sendBatch = function () { 587 | // Do not clear the batch timer if you don't go ahead here because 588 | // a send is already in progress. Otherwise the messages that were stopped from going out 589 | // may get ignored because the batch timer never went off. 590 | if (this.nbrLogItemsBeingSent > 0) { 591 | return; 592 | } 593 | clearTimer(this.batchTimeoutTimer); 594 | if (this.batchBuffer.length == 0) { 595 | return; 596 | } 597 | // Decided at this point to send contents of the buffer 598 | this.nbrLogItemsBeingSent = this.batchBuffer.length; 599 | var that = this; 600 | setTimer(this.sendTimeoutTimer, this.sendTimeout, function () { 601 | that.onSendingEnded.call(that); 602 | }); 603 | this.sendLogItems(this.batchBuffer, function () { 604 | // Log entries have been successfully sent to server 605 | // Remove the first (nbrLogItemsBeingSent) items in the batch buffer, because they are the ones 606 | // that were sent. 607 | that.batchBuffer.splice(0, that.nbrLogItemsBeingSent); 608 | // If items had to be skipped, add a WARN message 609 | if (that.nbrLogItemsSkipped > 0) { 610 | that.batchBuffer.push(newLogItem(getWarnLevel(), "Lost " + that.nbrLogItemsSkipped + " messages. Either connection with the server was down or logging was disabled via the enabled option. Reduce lost messages by increasing the ajaxAppender option maxBatchSize.", that.appenderName)); 611 | that.nbrLogItemsSkipped = 0; 612 | } 613 | that.onSendingEnded.call(that); 614 | }); 615 | }; 616 | return Appender; 617 | }()); 618 | JL.Appender = Appender; 619 | // --------------------- 620 | var AjaxAppender = /** @class */ (function (_super) { 621 | __extends(AjaxAppender, _super); 622 | function AjaxAppender(appenderName) { 623 | return _super.call(this, appenderName, AjaxAppender.prototype.sendLogItemsAjax) || this; 624 | } 625 | AjaxAppender.prototype.setOptions = function (options) { 626 | copyProperty("url", options, this); 627 | copyProperty("beforeSend", options, this); 628 | _super.prototype.setOptions.call(this, options); 629 | return this; 630 | }; 631 | AjaxAppender.prototype.sendLogItemsAjax = function (logItems, successCallback) { 632 | // JSON.stringify is only supported on IE8+ 633 | // Use try-catch in case we get an exception here. 634 | // 635 | // The "r" field is now obsolete. When writing a server side component, 636 | // read the HTTP header "JSNLog-RequestId" 637 | // to get the request id. 638 | // 639 | // The .Net server side component 640 | // now uses the JSNLog-RequestId HTTP Header, because this allows it to 641 | // detect whether the incoming request has a request id. 642 | // If the request id were in the json payload, it would have to read the json 643 | // from the stream, interfering with normal non-logging requests. 644 | // 645 | // To see what characters you can use in the HTTP header, visit: 646 | // http://stackoverflow.com/questions/3561381/custom-http-headers-naming-conventions/3561399#3561399 647 | // 648 | // It needs this ability, so users of NLog can set a requestId variable in NLog 649 | // before the server side component tries to log the client side log message 650 | // through an NLog logger. 651 | // Unlike Log4Net, NLog doesn't allow you to register an object whose ToString() 652 | // is only called when it tries to log something, so the requestId has to be 653 | // determined right at the start of request processing. 654 | try { 655 | // Do not send logs, if JL.enabled is set to false. 656 | // 657 | // Do not call successCallback here. After each timeout, jsnlog will retry sending the message. 658 | // If jsnlog gets re-enabled, it will then log the number of messages logged. 659 | // If it doesn't get re-enabled, amount of cpu cycles wasted is minimal. 660 | if (!allow(this)) { 661 | return; 662 | } 663 | // If a request is in progress, abort it. 664 | // Otherwise, it may call the success callback, which will be very confusing. 665 | // It may also stop the inflight request from resulting in a log at the server. 666 | if (this.xhr && (this.xhr.readyState != 0) && (this.xhr.readyState != 4)) { 667 | this.xhr.abort(); 668 | } 669 | // Because a react-native XMLHttpRequest cannot be reused it needs to be recreated with each request 670 | this.xhr = JL._createXMLHttpRequest(); 671 | // Only determine the url right before you send a log request. 672 | // Do not set the url when constructing the appender. 673 | // 674 | // This is because the server side component sets defaultAjaxUrl 675 | // in a call to setOptions, AFTER the JL object and the default appender 676 | // have been created. 677 | var ajaxUrl = "/jsnlog.logger"; 678 | // This evaluates to true if defaultAjaxUrl is null or undefined 679 | if (!(JL.defaultAjaxUrl == null)) { 680 | ajaxUrl = JL.defaultAjaxUrl; 681 | } 682 | if (this.url) { 683 | ajaxUrl = this.url; 684 | } 685 | this.xhr.open('POST', ajaxUrl); 686 | this.xhr.setRequestHeader('Content-Type', 'application/json'); 687 | this.xhr.setRequestHeader('JSNLog-RequestId', JL.requestId); 688 | var that = this; 689 | this.xhr.onreadystatechange = function () { 690 | // On most browsers, if the request fails (eg. internet is gone), 691 | // it will set xhr.readyState == 4 and xhr.status != 200 (0 if request could not be sent) immediately. 692 | // However, Edge and IE will not change the readyState at all if the internet goes away while waiting 693 | // for a response. 694 | // Some servers will return a 204 (success, no content) when the JSNLog endpoint 695 | // returns the empty response. So check on any code in the 2.. range, not just 200. 696 | if ((that.xhr.readyState == 4) && (that.xhr.status >= 200 && that.xhr.status < 300)) { 697 | successCallback(); 698 | } 699 | }; 700 | var json = { 701 | r: JL.requestId, 702 | lg: logItems 703 | }; 704 | // call beforeSend callback 705 | // first try the callback on the appender 706 | // then the global defaultBeforeSend callback 707 | if (typeof this.beforeSend === 'function') { 708 | this.beforeSend.call(this, this.xhr, json); 709 | } 710 | else if (typeof JL.defaultBeforeSend === 'function') { 711 | JL.defaultBeforeSend.call(this, this.xhr, json); 712 | } 713 | var finalmsg = JSON.stringify(json); 714 | this.xhr.send(finalmsg); 715 | } 716 | catch (e) { } 717 | }; 718 | return AjaxAppender; 719 | }(Appender)); 720 | JL.AjaxAppender = AjaxAppender; 721 | // --------------------- 722 | var ConsoleAppender = /** @class */ (function (_super) { 723 | __extends(ConsoleAppender, _super); 724 | function ConsoleAppender(appenderName) { 725 | return _super.call(this, appenderName, ConsoleAppender.prototype.sendLogItemsConsole) || this; 726 | } 727 | ConsoleAppender.prototype.clog = function (logEntry) { 728 | JL._console.log(logEntry); 729 | }; 730 | ConsoleAppender.prototype.cerror = function (logEntry) { 731 | if (JL._console.error) { 732 | JL._console.error(logEntry); 733 | } 734 | else { 735 | this.clog(logEntry); 736 | } 737 | }; 738 | ConsoleAppender.prototype.cwarn = function (logEntry) { 739 | if (JL._console.warn) { 740 | JL._console.warn(logEntry); 741 | } 742 | else { 743 | this.clog(logEntry); 744 | } 745 | }; 746 | ConsoleAppender.prototype.cinfo = function (logEntry) { 747 | if (JL._console.info) { 748 | JL._console.info(logEntry); 749 | } 750 | else { 751 | this.clog(logEntry); 752 | } 753 | }; 754 | // IE11 has a console.debug function. But its console doesn't have 755 | // the option to show/hide debug messages (the same way Chrome and FF do), 756 | // even though it does have such buttons for Error, Warn, Info. 757 | // 758 | // For now, this means that debug messages can not be hidden on IE. 759 | // Live with this, seeing that it works fine on FF and Chrome, which 760 | // will be much more popular with developers. 761 | ConsoleAppender.prototype.cdebug = function (logEntry) { 762 | if (JL._console.debug) { 763 | JL._console.debug(logEntry); 764 | } 765 | else { 766 | this.cinfo(logEntry); 767 | } 768 | }; 769 | ConsoleAppender.prototype.sendLogItemsConsole = function (logItems, successCallback) { 770 | try { 771 | // Do not send logs, if JL.enabled is set to false 772 | // 773 | // Do not call successCallback here. After each timeout, jsnlog will retry sending the message. 774 | // If jsnlog gets re-enabled, it will then log the number of messages logged. 775 | // If it doesn't get re-enabled, amount of cpu cycles wasted is minimal. 776 | if (!allow(this)) { 777 | return; 778 | } 779 | if (!JL._console) { 780 | return; 781 | } 782 | var i; 783 | for (i = 0; i < logItems.length; ++i) { 784 | var li = logItems[i]; 785 | var msg = li.n + ": " + li.m; 786 | // Only log the timestamp if we're on the server 787 | // (window is undefined). On the browser, the user 788 | // sees the log entry probably immediately, so in that case 789 | // the timestamp is clutter. 790 | if (typeof window === 'undefined') { 791 | msg = new Date(li.t) + " | " + msg; 792 | } 793 | if (li.l <= JL.getDebugLevel()) { 794 | this.cdebug(msg); 795 | } 796 | else if (li.l <= JL.getInfoLevel()) { 797 | this.cinfo(msg); 798 | } 799 | else if (li.l <= JL.getWarnLevel()) { 800 | this.cwarn(msg); 801 | } 802 | else { 803 | this.cerror(msg); 804 | } 805 | } 806 | } 807 | catch (e) { 808 | } 809 | successCallback(); 810 | }; 811 | return ConsoleAppender; 812 | }(Appender)); 813 | JL.ConsoleAppender = ConsoleAppender; 814 | // -------------------- 815 | var Logger = /** @class */ (function () { 816 | function Logger(loggerName) { 817 | this.loggerName = loggerName; 818 | // Create seenRexes, otherwise this logger will use the seenRexes 819 | // of its parent via the prototype chain. 820 | this.seenRegexes = []; 821 | } 822 | Logger.prototype.setOptions = function (options) { 823 | copyProperty("level", options, this); 824 | copyProperty("userAgentRegex", options, this); 825 | copyProperty("disallow", options, this); 826 | copyProperty("ipRegex", options, this); 827 | copyProperty("appenders", options, this); 828 | copyProperty("onceOnly", options, this); 829 | // Reset seenRegexes, in case onceOnly has been changed. 830 | this.seenRegexes = []; 831 | return this; 832 | }; 833 | // Turns an exception into an object that can be sent to the server. 834 | Logger.prototype.buildExceptionObject = function (e) { 835 | var excObject = {}; 836 | if (e.stack) { 837 | excObject.stack = e.stack; 838 | } 839 | else { 840 | excObject.e = e; 841 | } 842 | if (e.message) { 843 | excObject.message = e.message; 844 | } 845 | if (e.name) { 846 | excObject.name = e.name; 847 | } 848 | if (e.data) { 849 | excObject.data = e.data; 850 | } 851 | if (e.inner) { 852 | excObject.inner = this.buildExceptionObject(e.inner); 853 | } 854 | return excObject; 855 | }; 856 | // Logs a log item. 857 | // Parameter e contains an exception (or null or undefined). 858 | // 859 | // Reason that processing exceptions is done at this low level is that 860 | // 1) no need to spend the cpu cycles if the logger is switched off 861 | // 2) fatalException takes both a logObject and an exception, and the logObject 862 | // may be a function that should only be executed if the logger is switched on. 863 | // 864 | // If an exception is passed in, the contents of logObject is attached to the exception 865 | // object in a new property logData. 866 | // The resulting exception object is than worked into a message to the server. 867 | // 868 | // If there is no exception, logObject itself is worked into the message to the server. 869 | Logger.prototype.log = function (level, logObject, e) { 870 | var i = 0; 871 | var compositeMessage; 872 | var excObject; 873 | // If we can't find any appenders, do nothing 874 | if (!this.appenders) { 875 | return this; 876 | } 877 | if (((level >= this.level)) && allow(this)) { 878 | if (e) { 879 | excObject = this.buildExceptionObject(e); 880 | excObject.logData = stringifyLogObjectFunction(logObject); 881 | } 882 | else { 883 | excObject = logObject; 884 | } 885 | compositeMessage = stringifyLogObject(excObject); 886 | if (allowMessage(this, compositeMessage.finalString)) { 887 | // See whether message is a duplicate 888 | if (this.onceOnly) { 889 | i = this.onceOnly.length - 1; 890 | while (i >= 0) { 891 | if (new RegExp(this.onceOnly[i]).test(compositeMessage.finalString)) { 892 | if (this.seenRegexes[i]) { 893 | return this; 894 | } 895 | this.seenRegexes[i] = true; 896 | } 897 | i--; 898 | } 899 | } 900 | // Pass message to all appenders 901 | // Note that these appenders could be Winston transports 902 | // https://github.com/flatiron/winston 903 | compositeMessage.meta = compositeMessage.meta || {}; 904 | // Note that if the user is logging an object, compositeMessage.meta will hold a reference to that object. 905 | // Do not add fields to compositeMessage.meta, otherwise the user's object will get that field out of the blue. 906 | i = this.appenders.length - 1; 907 | while (i >= 0) { 908 | this.appenders[i].log(levelToString(level), compositeMessage.msg, compositeMessage.meta, function () { }, level, compositeMessage.finalString, this.loggerName); 909 | i--; 910 | } 911 | } 912 | } 913 | return this; 914 | }; 915 | Logger.prototype.trace = function (logObject) { return this.log(getTraceLevel(), logObject); }; 916 | Logger.prototype.debug = function (logObject) { return this.log(getDebugLevel(), logObject); }; 917 | Logger.prototype.info = function (logObject) { return this.log(getInfoLevel(), logObject); }; 918 | Logger.prototype.warn = function (logObject) { return this.log(getWarnLevel(), logObject); }; 919 | Logger.prototype.error = function (logObject) { return this.log(getErrorLevel(), logObject); }; 920 | Logger.prototype.fatal = function (logObject) { return this.log(getFatalLevel(), logObject); }; 921 | Logger.prototype.fatalException = function (logObject, e) { return this.log(getFatalLevel(), logObject, e); }; 922 | return Logger; 923 | }()); 924 | JL.Logger = Logger; 925 | function createAjaxAppender(appenderName) { 926 | return new AjaxAppender(appenderName); 927 | } 928 | JL.createAjaxAppender = createAjaxAppender; 929 | function createConsoleAppender(appenderName) { 930 | return new ConsoleAppender(appenderName); 931 | } 932 | JL.createConsoleAppender = createConsoleAppender; 933 | // ----------------------- 934 | // In the browser, the default appender is the AjaxAppender. 935 | // Under nodejs (where there is no "window"), use the ConsoleAppender instead. 936 | // 937 | // Do NOT create an AjaxAppender object if you are not on a browser (that is, window is not defined). 938 | // That would try to create an XmlHttpRequest object, which will crash outside a browser. 939 | var defaultAppender; 940 | if (typeof window !== 'undefined') { 941 | defaultAppender = new AjaxAppender(""); 942 | } 943 | else { 944 | defaultAppender = new ConsoleAppender(""); 945 | } 946 | // Create root logger 947 | // 948 | // Note that this is the parent of all other loggers. 949 | // Logger "x" will be stored at 950 | // JL.__.x 951 | // Logger "x.y" at 952 | // JL.__.x.y 953 | JL.__ = new JL.Logger(""); 954 | JL.__.setOptions({ 955 | level: JL.getDebugLevel(), 956 | appenders: [defaultAppender] 957 | }); 958 | })(JL || (JL = {})); 959 | if (typeof exports !== 'undefined') { 960 | // Allows SystemJs to import jsnlog.js. See 961 | // https://github.com/mperdeck/jsnlog.js/issues/56 962 | exports.__esModule = true; 963 | exports.JL = JL; 964 | } 965 | // Support AMD module format 966 | var define; 967 | if (typeof define == 'function' && define.amd) { 968 | define('jsnlog', [], function () { 969 | return JL; 970 | }); 971 | } 972 | // If the __jsnlog_configure global function has been 973 | // created, call it now. This allows you to create a global function 974 | // setting logger options etc. inline in the page before jsnlog.js 975 | // has been loaded. 976 | if (typeof __jsnlog_configure == 'function') { 977 | __jsnlog_configure(JL); 978 | } 979 | // Create onerror handler to log uncaught exceptions to the server side log, but only if there 980 | // is no such handler already. 981 | // Must use "typeof window" here, because in NodeJs, window is not defined at all, so cannot refer to window in any way. 982 | if (typeof window !== 'undefined' && !window.onerror) { 983 | window.onerror = function (errorMsg, url, lineNumber, column, errorObj) { 984 | // Send object with all data to server side log, using severity fatal, 985 | // from logger "onerrorLogger" 986 | // 987 | // Use errorMsg.message if available, so Angular 4 template errors will be logged. 988 | // See https://github.com/mperdeck/jsnlog.js/pull/68 989 | JL("onerrorLogger").fatalException({ 990 | "msg": "Uncaught Exception", 991 | "errorMsg": errorMsg ? (errorMsg.message || errorMsg) : '', 992 | "url": url, 993 | "line number": lineNumber, "column": column 994 | }, errorObj); 995 | // Tell browser to run its own error handler as well 996 | return false; 997 | }; 998 | } 999 | // Deal with unhandled exceptions thrown in promises 1000 | if (typeof window !== 'undefined' && !window.onunhandledrejection) { 1001 | window.onunhandledrejection = function (event) { 1002 | // Send object with all data to server side log, using severity fatal, 1003 | // from logger "onerrorLogger". 1004 | // Need to check both event.reason.message and event.message, 1005 | // because SystemJs wraps exceptions and throws a new object which doesn't have a reason property. 1006 | // See https://github.com/systemjs/systemjs/issues/1309 1007 | JL("onerrorLogger").fatalException({ 1008 | "msg": "unhandledrejection", 1009 | "errorMsg": event.reason ? event.reason.message : event.message || null 1010 | }, event.reason); 1011 | }; 1012 | } 1013 | 1014 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_Net5.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/JSNLogDemo_Core_Net5.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_Net5 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9004/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9004/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_Net5 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | // Configure JSNLog 49 | // Do this before calling UseStaticFiles. 50 | // 51 | // For configuration options, see 52 | // https://jsnlog.com/Documentation/Configuration 53 | app.UseJSNLog(loggerFactory); 54 | 55 | 56 | 57 | 58 | app.UseStaticFiles(); 59 | 60 | app.UseRouting(); 61 | 62 | app.UseAuthorization(); 63 | 64 | app.UseEndpoints(endpoints => 65 | { 66 | endpoints.MapControllerRoute( 67 | name: "default", 68 | pattern: "{controller=Home}/{action=Index}/{id?}"); 69 | }); 70 | } 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_Net5

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net5/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_Net6.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/JSNLogDemo_Core_Net6.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_Net6 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9003/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9003/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_Net6 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | // Configure JSNLog 49 | // Do this before calling UseStaticFiles. 50 | // 51 | // For configuration options, see 52 | // https://jsnlog.com/Documentation/Configuration 53 | app.UseJSNLog(loggerFactory); 54 | 55 | 56 | 57 | 58 | app.UseStaticFiles(); 59 | 60 | app.UseRouting(); 61 | 62 | app.UseAuthorization(); 63 | 64 | app.UseEndpoints(endpoints => 65 | { 66 | endpoints.MapControllerRoute( 67 | name: "default", 68 | pattern: "{controller=Home}/{action=Index}/{id?}"); 69 | }); 70 | } 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_Net6

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net6/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_Net7.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/JSNLogDemo_Core_Net7.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_Net7 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9002/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9002/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_Net7 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | // Configure JSNLog 49 | // Do this before calling UseStaticFiles. 50 | // 51 | // For configuration options, see 52 | // https://jsnlog.com/Documentation/Configuration 53 | app.UseJSNLog(loggerFactory); 54 | 55 | 56 | 57 | 58 | app.UseStaticFiles(); 59 | 60 | app.UseRouting(); 61 | 62 | app.UseAuthorization(); 63 | 64 | app.UseEndpoints(endpoints => 65 | { 66 | endpoints.MapControllerRoute( 67 | name: "default", 68 | pattern: "{controller=Home}/{action=Index}/{id?}"); 69 | }); 70 | } 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_Net7

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_Net7_CORS.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/JSNLogDemo_Core_Net7_CORS.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_Net7_CORS 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | false 8 | false 9 | true 10 | Debug 11 | Any CPU 12 | FileSystem 13 | bin\Debug\net7.0\publish\ 14 | FileSystem 15 | <_TargetId>Folder 16 | 17 | net7.0 18 | 50f19253-8526-4f9c-bfcd-906c8c3c3dac 19 | false 20 | 21 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9000/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9000/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_Net7_CORS 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | // Configure JSNLog 49 | // Do this before calling UseStaticFiles. 50 | // 51 | // For configuration options, see 52 | // https://jsnlog.com/Documentation/Configuration 53 | app.UseJSNLog(loggerFactory, new JsnlogConfiguration() 54 | { 55 | insertJsnlogInHtmlResponses = true, 56 | productionLibraryPath = "https://cdnjs.cloudflare.com/ajax/libs/jsnlog/2.30.0/jsnlog.min.js", 57 | defaultAjaxUrl = "http://apicorslocalhost.local/jsnlog.logger", 58 | 59 | // Allow requests from localhost (the host used when hitting F5 in Visual Studio) 60 | corsAllowedOriginsRegex = @"^https?:\/\/([a-z0-9]+[.])*localhost.*", 61 | 62 | // Allow custom headers X-MyHeader and X-MyHeader2 63 | corsAllowedHeaders = "X-MyHeader, X-MyHeader2" 64 | }); 65 | 66 | 67 | 68 | 69 | app.UseStaticFiles(); 70 | 71 | app.UseRouting(); 72 | 73 | app.UseAuthorization(); 74 | 75 | app.UseEndpoints(endpoints => 76 | { 77 | endpoints.MapControllerRoute( 78 | name: "default", 79 | pattern: "{controller=Home}/{action=Index}/{id?}"); 80 | }); 81 | } 82 | } 83 | } 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_Net7_CORS

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 | 16 |

17 | This demo site shows the CORS feature, and so uses 2 domains: 18 |

    19 |
  1. 20 | apicorslocalhost.local - log requests will be sent here. Will be hosted in IIS for this demo. 21 |
  2. 22 |
  3. 23 | localhost - web site sending log request to apicorslocalhost.local. Started by hitting F5. 24 |
  4. 25 |
26 | 27 |

28 | This means you have to host the demo site as apicorslocalhost.local in IIS, so the demo site running in localhost can send log requests to it: 29 |

30 |
    31 |
  1. 32 | If you haven't already done so, install IIS. 33 |

    34 |

  2. 35 |
  3. 36 | Also ensure you have the ASP.NET Core Module/Hosting Bundle installed. 37 |

    38 |

  4. 39 |
  5. 40 | Add apicorslocalhost.local to your hosts file, so the browser resolves it to the loopback IP address: 41 |
    # normally at C:\Windows\System32\drivers\etc\hosts
     42 | 	127.0.0.1       apicorslocalhost.local
    43 |

    44 |

  6. 45 |
  7. 46 | Publish the site, so it can run from IIS: 47 |
      48 |
    1. 49 | Right click JSNLogDemo_Core_Net7_CORS project; 50 |
    2. 51 |
    3. 52 | Choose Publish option; 53 |
    4. 54 |
    5. 55 | Click Publish button (top right); 56 |
    6. 57 |
    7. 58 | It will have published to bin\Release\net7.0\publish\. 59 |
    8. 60 |
    61 |

    62 |

  8. 63 | Open a command prompt (cmd) with administrator priviliges, and run these commands to add apicorslocalhost.local to IIS 64 | (assumes your jsnlogSimpleWorkingDemos sits under C:\Dev\JSNLog, change if needed): 65 |
     66 | appcmd add apppool /name:apicorslocalhost
     67 | appcmd add site /name:apicorslocalhost /physicalPath:"C:\Dev\JSNLog\jsnlogSimpleWorkingDemos\jsnlogSimpleWorkingDemos\NetCore\JSNLogDemo_Core_Net7_CORS\bin\Debug\net7.0\publish" /bindings:http/*:80:apicorslocalhost.local
     68 | appcmd set site /site.name:apicorslocalhost /[path='/'].applicationPool:apicorslocalhost
     69 | appcmd start site /site.name:apicorslocalhost
     70 | 
    71 | 72 |

    73 |

  9. 74 |
75 | 76 | 77 |

78 | The recommended way to run this demo project is to: 79 |

    80 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 81 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 82 |
83 |

84 |

85 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 86 | including client log messages. 87 |

88 |

89 | You will see those messages in the Output window in Visual Studio. 90 |

91 | 92 |

93 | To see the contents of the client side log messages as they travel from the browser to the server: 94 |

    95 |
  1. Right click anywhere in this page | Inspect
  2. 96 |
  3. Click Network tab (right hand side)
  4. 97 |
  5. Click Fetch/XHR tab
  6. 98 |
  7. F5 to reload the page, so it sends the log messages again
  8. 99 |
100 |

101 | 102 |

If you are running this on Chrome

103 |

104 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 105 |

106 |

107 | The solution is to use another browser, such as Microsoft Edge. 108 |

109 | 110 |

How it works

111 |

112 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 113 | However, it will only do that if window.onerror has not already been set 114 | (details). That way, if you are setting your own onerror handler, it won't override that. 115 |

116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_CORS/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_Net7_beforeSend.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/JSNLogDemo_Core_Net7_beforeSend.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_Net7_beforeSend 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9001/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9001/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_Net7_beforeSend 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | // Configure JSNLog 49 | // Do this before calling UseStaticFiles. 50 | // 51 | // For configuration options, see 52 | // https://jsnlog.com/Documentation/Configuration 53 | app.UseJSNLog(loggerFactory); 54 | 55 | 56 | 57 | 58 | app.UseStaticFiles(); 59 | 60 | app.UseRouting(); 61 | 62 | app.UseAuthorization(); 63 | 64 | app.UseEndpoints(endpoints => 65 | { 66 | endpoints.MapControllerRoute( 67 | name: "default", 68 | pattern: "{controller=Home}/{action=Index}/{id?}"); 69 | }); 70 | } 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_Net7_beforeSend

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_Net7_beforeSend/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // ----------------------- 8 | // beforeSend example 9 | // 10 | // Shows a number of things you can do by setting the beforeSend option 11 | // to a function. 12 | 13 | var beforeSendExample = function (xhr, json) { 14 | 15 | // ------------------------------------------------------------------ 16 | // Modify the message of the log request to the server. 17 | 18 | json.lg[0].m += " - added by function beforeSendExample"; 19 | 20 | // ------------------------------------------------------------------ 21 | // Add request header 22 | 23 | xhr.setRequestHeader('X-MyHeader', 'My header value'); 24 | }; 25 | 26 | // Create new appender, so you can set its beforeSend option. 27 | var appender = JL.createAjaxAppender("example appender"); 28 | appender.setOptions({ 29 | "beforeSend": beforeSendExample 30 | }); 31 | 32 | // Get the root logger to use the new appender. 33 | JL().setOptions({ 34 | "appenders": [appender] 35 | }); 36 | 37 | // ----- end of beforeSend example ------- 38 | 39 | 40 | // Log with every severity 41 | JL("jsLogger").debug("debug client log message"); 42 | JL("jsLogger").info("info client log message"); 43 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 44 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 45 | JL("jsLogger").fatal("fatal client log message"); 46 | 47 | // Log caught exception 48 | try { 49 | // ReferenceError: xyz is not defined 50 | xyz; 51 | } catch (e) { 52 | // Log the exception 53 | JL().fatalException("Something went wrong!", e); 54 | } 55 | 56 | // ReferenceError: xyz2 is not defined. 57 | xyz2; 58 | }); 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_NetCoreApp2.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/JSNLogDemo_Core_NetCoreApp2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace JSNLogDemo_Core_NetCoreApp2 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9007/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9007/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | using JSNLog; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace JSNLogDemo_Core_NetCoreApp2 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | public void ConfigureServices(IServiceCollection services) 26 | { 27 | services.AddMvc(); 28 | } 29 | 30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 31 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 32 | { 33 | 34 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 35 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 36 | // 37 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 38 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 39 | 40 | 41 | if (env.IsDevelopment()) 42 | { 43 | app.UseDeveloperExceptionPage(); 44 | app.UseBrowserLink(); 45 | } 46 | else 47 | { 48 | app.UseExceptionHandler("/Home/Error"); 49 | } 50 | 51 | 52 | // Configure JSNLog 53 | // Do this before calling UseStaticFiles. 54 | // 55 | // For configuration options, see 56 | // https://jsnlog.com/Documentation/Configuration 57 | app.UseJSNLog(loggerFactory, new JsnlogConfiguration()); 58 | 59 | 60 | app.UseStaticFiles(); 61 | 62 | app.UseMvc(routes => 63 | { 64 | routes.MapRoute( 65 | name: "default", 66 | template: "{controller=Home}/{action=Index}/{id?}"); 67 | }); 68 | } 69 | } 70 | } 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_NetCoreApp2

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp2/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_Core_NetCoreApp3.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/JSNLogDemo_Core_NetCoreApp3.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace JSNLogDemo_Core_NetCoreApp3 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9005/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9005/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_Core_NetCoreApp3 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | // JSNLog simply passes incoming client side log messages to the standard Net Core logging infrastructure. 32 | // As a result, those messages wind up in the same logs where your server side log messages are stored. 33 | // 34 | // By default, Net Core sends all log messages to the console. If you run this site by hitting F5 in Visual Studio, you will see 35 | // those messages in the output window in Visual Studio. This will include the client side log messages sent by JSNLog. 36 | 37 | 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | 48 | // Configure JSNLog 49 | // Do this before calling UseStaticFiles. 50 | // 51 | // For configuration options, see 52 | // https://jsnlog.com/Documentation/Configuration 53 | app.UseJSNLog(loggerFactory); 54 | 55 | 56 | 57 | 58 | app.UseStaticFiles(); 59 | 60 | app.UseRouting(); 61 | 62 | app.UseAuthorization(); 63 | 64 | app.UseEndpoints(endpoints => 65 | { 66 | endpoints.MapControllerRoute( 67 | name: "default", 68 | pattern: "{controller=Home}/{action=Index}/{id?}"); 69 | }); 70 | } 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_Core_NetCoreApp3

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_Core_NetCoreApp3/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace JSNLogDemo_NLog_NetCoreRequestId.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | readonly ILogger _log; 14 | 15 | public HomeController(ILogger log) 16 | { 17 | _log = log; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | _log.LogInformation("info server log message"); 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/JSNLogDemo_NLog_NetCoreRequestId.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netcoreapp3.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Always 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/NLog.config: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | using NLog.Web; 11 | 12 | /// 13 | /// See 14 | /// https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2 15 | /// 16 | 17 | namespace JSNLogDemo_NLog_NetCoreRequestId 18 | { 19 | public class Program 20 | { 21 | public static void Main(string[] args) 22 | { 23 | // NLog: setup the logger first to catch all errors 24 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); 25 | 26 | // Allows for 27 | var currentDir = Directory.GetCurrentDirectory(); 28 | NLog.LogManager.Configuration.Variables["logDirectory"] = currentDir; 29 | 30 | try 31 | { 32 | logger.Debug("init main"); 33 | BuildWebHost(args).Build().Run(); 34 | } 35 | catch (Exception ex) 36 | { 37 | //NLog: catch setup errors 38 | logger.Error(ex, "Stopped program because of exception"); 39 | throw; 40 | } 41 | finally 42 | { 43 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) 44 | NLog.LogManager.Shutdown(); 45 | } 46 | } 47 | 48 | public static IWebHostBuilder BuildWebHost(string[] args) => 49 | WebHost.CreateDefaultBuilder(args) 50 | .UseStartup() 51 | .ConfigureLogging(logging => 52 | { 53 | logging.ClearProviders(); 54 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); 55 | }) 56 | .UseNLog(); // NLog: setup NLog for Dependency injection} 57 | } 58 | } 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:9008/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:9008/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using JSNLog; 8 | 9 | 10 | namespace JSNLogDemo_NLog_NetCoreRequestId 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddRazorPages(); 25 | } 26 | 27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 28 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) 29 | { 30 | 31 | 32 | if (env.IsDevelopment()) 33 | { 34 | app.UseDeveloperExceptionPage(); 35 | } 36 | else 37 | { 38 | app.UseExceptionHandler("/Error"); 39 | } 40 | 41 | 42 | // Configure JSNLog 43 | // Do this before calling UseStaticFiles. 44 | // 45 | // For configuration options, see 46 | // https://jsnlog.com/Documentation/Configuration 47 | app.UseJSNLog(loggerFactory, new JsnlogConfiguration()); 48 | 49 | 50 | 51 | 52 | app.UseStaticFiles(); 53 | 54 | app.UseRouting(); 55 | 56 | app.UseAuthorization(); 57 | 58 | app.UseEndpoints(endpoints => 59 | { 60 | endpoints.MapControllerRoute( 61 | name: "default", 62 | pattern: "{controller=Home}/{action=Index}/{id?}"); 63 | }); 64 | } 65 | } 66 | } 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

JSNLogDemo_NLog_NetCoreRequestId

9 |

Welcome to this simple demo

10 |

11 | This page loads file js/jsnlogdemo.js (contained in this web project). 12 | It has a few lines of simple JavaScript code to send log messages to the server immediately when the file loads. Have a look. 13 |

14 | 15 |

16 | The recommended way to run this demo project is to: 17 |

    18 |
  1. Make this project the start up project - right click the project | Set as Startup Project.
  2. 19 |
  3. Hit F5 to open the home page of the site in your browser.
  4. 20 |
21 |

22 |

23 | This simple demo site uses the default Net Core logging infrastructure. As a result, all log messages will go to the console, 24 | including client log messages. 25 |

26 |

27 | You will see those messages in the Output window in Visual Studio. 28 |

29 | 30 |

31 | To see the contents of the client side log messages as they travel from the browser to the server: 32 |

    33 |
  1. Right click anywhere in this page | Inspect
  2. 34 |
  3. Click Network tab (right hand side)
  4. 35 |
  5. Click Fetch/XHR tab
  6. 36 |
  7. F5 to reload the page, so it sends the log messages again
  8. 37 |
38 |

39 | 40 |

If you are running this on Chrome

41 |

42 | The demo page loads jsnlog.min.js from a CDN. Chrome is known to block this request when the page is served from localhost. As a result, the log entries may not appear in the Output window. 43 |

44 |

45 | The solution is to use another browser, such as Microsoft Edge. 46 |

47 | 48 |

How it works

49 |

50 | JSNLog sets the window.onerror handler when it loads, so uncaught JavaScript exceptions are sent to your server side log. 51 | However, it will only do that if window.onerror has not already been set 52 | (details). That way, if you are setting your own onerror handler, it won't override that. 53 |

54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | 4 |

Development Mode

5 |

6 | Swapping to Development environment will display more detailed information about the error that occurred. 7 |

8 |

9 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @addTagHelper "*, jsnlog" 3 | 4 | 5 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Trace", 5 | "Microsoft": "Information" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mperdeck/jsnlogSimpleWorkingDemos/75d22f1beb3eda93b6d3642b1bfcf0ed97fe1b39/jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/wwwroot/favicon.ico -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/NetCore/JSNLogDemo_NLog_NetCoreRequestId/wwwroot/js/jsnlogdemo.js: -------------------------------------------------------------------------------- 1 | 2 | // Run this code once the page is fully loaded (including all JavaScript files) 3 | window.addEventListener("load", function () { 4 | 5 | 6 | 7 | // Log with every severity 8 | JL("jsLogger").debug("debug client log message"); 9 | JL("jsLogger").info("info client log message"); 10 | JL("jsLogger").warn({ msg: 'warn client log message - logging object', x: 5, y: 88 }); 11 | JL("jsLogger").error(function() { return "error client log message - returned by function"; }); 12 | JL("jsLogger").fatal("fatal client log message"); 13 | 14 | // Log caught exception 15 | try { 16 | // ReferenceError: xyz is not defined 17 | xyz; 18 | } catch (e) { 19 | // Log the exception 20 | JL().fatalException("Something went wrong!", e); 21 | } 22 | 23 | // ReferenceError: xyz2 is not defined. 24 | xyz2; 25 | }); 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jsnlogSimpleWorkingDemos/jsnlogSimpleWorkingDemos.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetCore", "NetCore", "{8396E2E9-6D1D-45E3-A00C-E351862CAF12}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_Net4x", "NetCore\JSNLogDemo_Core_Net4x\JSNLogDemo_Core_Net4x.csproj", "{8A1A4ACA-7297-4055-BDC9-5732A4C0AC4E}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_NetCoreApp2", "NetCore\JSNLogDemo_Core_NetCoreApp2\JSNLogDemo_Core_NetCoreApp2.csproj", "{40EA7B61-06A2-46DF-84E1-7A91F43E6644}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_NLog_NetCoreRequestId", "NetCore\JSNLogDemo_NLog_NetCoreRequestId\JSNLogDemo_NLog_NetCoreRequestId.csproj", "{5E609525-8F19-4E6A-8F15-15ADF778D126}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_NetCoreApp3", "NetCore\JSNLogDemo_Core_NetCoreApp3\JSNLogDemo_Core_NetCoreApp3.csproj", "{9A5207B4-1A56-468C-A4EC-EC1DC27AF83E}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_Net5", "NetCore\JSNLogDemo_Core_Net5\JSNLogDemo_Core_Net5.csproj", "{84B0E492-24C3-4B52-BF61-6E7EC99E74AE}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_Net6", "NetCore\JSNLogDemo_Core_Net6\JSNLogDemo_Core_Net6.csproj", "{2CD5A2A6-8865-4D1B-B02E-0BB8E635FF13}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_Net7", "NetCore\JSNLogDemo_Core_Net7\JSNLogDemo_Core_Net7.csproj", "{CD30D528-82CB-42DA-BA18-4ABCF0A42AE7}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_LoggingEventHandlers", "NetCore\JSNLogDemo_Core_LoggingEventHandlers\JSNLogDemo_Core_LoggingEventHandlers.csproj", "{E087FCD3-A2BC-409F-9391-F0286D4CD292}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_DefaultAjaxUrl", "NetCore\JSNLogDemo_Core_DefaultAjaxUrl\JSNLogDemo_Core_DefaultAjaxUrl.csproj", "{3959281A-40A0-4E17-A349-060CFA936C45}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSNLogDemo_Core_Net7_beforeSend", "NetCore\JSNLogDemo_Core_Net7_beforeSend\JSNLogDemo_Core_Net7_beforeSend.csproj", "{F35F90BA-6248-4340-8DB4-E7D3A591EE1F}" 27 | EndProject 28 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JSNLogDemo_Core_Net7_CORS", "NetCore\JSNLogDemo_Core_Net7_CORS\JSNLogDemo_Core_Net7_CORS.csproj", "{50F19253-8526-4F9C-BFCD-906C8C3C3DAC}" 29 | EndProject 30 | Global 31 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 32 | Debug|Any CPU = Debug|Any CPU 33 | Release|Any CPU = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 36 | {8A1A4ACA-7297-4055-BDC9-5732A4C0AC4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {8A1A4ACA-7297-4055-BDC9-5732A4C0AC4E}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {8A1A4ACA-7297-4055-BDC9-5732A4C0AC4E}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {8A1A4ACA-7297-4055-BDC9-5732A4C0AC4E}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {40EA7B61-06A2-46DF-84E1-7A91F43E6644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {40EA7B61-06A2-46DF-84E1-7A91F43E6644}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {40EA7B61-06A2-46DF-84E1-7A91F43E6644}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {40EA7B61-06A2-46DF-84E1-7A91F43E6644}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {5E609525-8F19-4E6A-8F15-15ADF778D126}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {5E609525-8F19-4E6A-8F15-15ADF778D126}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {5E609525-8F19-4E6A-8F15-15ADF778D126}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {5E609525-8F19-4E6A-8F15-15ADF778D126}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {9A5207B4-1A56-468C-A4EC-EC1DC27AF83E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {9A5207B4-1A56-468C-A4EC-EC1DC27AF83E}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {9A5207B4-1A56-468C-A4EC-EC1DC27AF83E}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {9A5207B4-1A56-468C-A4EC-EC1DC27AF83E}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {84B0E492-24C3-4B52-BF61-6E7EC99E74AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {84B0E492-24C3-4B52-BF61-6E7EC99E74AE}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {84B0E492-24C3-4B52-BF61-6E7EC99E74AE}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {84B0E492-24C3-4B52-BF61-6E7EC99E74AE}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {2CD5A2A6-8865-4D1B-B02E-0BB8E635FF13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {2CD5A2A6-8865-4D1B-B02E-0BB8E635FF13}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {2CD5A2A6-8865-4D1B-B02E-0BB8E635FF13}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {2CD5A2A6-8865-4D1B-B02E-0BB8E635FF13}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {CD30D528-82CB-42DA-BA18-4ABCF0A42AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {CD30D528-82CB-42DA-BA18-4ABCF0A42AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {CD30D528-82CB-42DA-BA18-4ABCF0A42AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {CD30D528-82CB-42DA-BA18-4ABCF0A42AE7}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {E087FCD3-A2BC-409F-9391-F0286D4CD292}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {E087FCD3-A2BC-409F-9391-F0286D4CD292}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {E087FCD3-A2BC-409F-9391-F0286D4CD292}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {E087FCD3-A2BC-409F-9391-F0286D4CD292}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {3959281A-40A0-4E17-A349-060CFA936C45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {3959281A-40A0-4E17-A349-060CFA936C45}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {3959281A-40A0-4E17-A349-060CFA936C45}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {3959281A-40A0-4E17-A349-060CFA936C45}.Release|Any CPU.Build.0 = Release|Any CPU 72 | {F35F90BA-6248-4340-8DB4-E7D3A591EE1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {F35F90BA-6248-4340-8DB4-E7D3A591EE1F}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {F35F90BA-6248-4340-8DB4-E7D3A591EE1F}.Release|Any CPU.ActiveCfg = Release|Any CPU 75 | {F35F90BA-6248-4340-8DB4-E7D3A591EE1F}.Release|Any CPU.Build.0 = Release|Any CPU 76 | {50F19253-8526-4F9C-BFCD-906C8C3C3DAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 77 | {50F19253-8526-4F9C-BFCD-906C8C3C3DAC}.Debug|Any CPU.Build.0 = Debug|Any CPU 78 | {50F19253-8526-4F9C-BFCD-906C8C3C3DAC}.Release|Any CPU.ActiveCfg = Release|Any CPU 79 | {50F19253-8526-4F9C-BFCD-906C8C3C3DAC}.Release|Any CPU.Build.0 = Release|Any CPU 80 | EndGlobalSection 81 | GlobalSection(SolutionProperties) = preSolution 82 | HideSolutionNode = FALSE 83 | EndGlobalSection 84 | GlobalSection(NestedProjects) = preSolution 85 | {8A1A4ACA-7297-4055-BDC9-5732A4C0AC4E} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 86 | {40EA7B61-06A2-46DF-84E1-7A91F43E6644} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 87 | {5E609525-8F19-4E6A-8F15-15ADF778D126} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 88 | {9A5207B4-1A56-468C-A4EC-EC1DC27AF83E} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 89 | {84B0E492-24C3-4B52-BF61-6E7EC99E74AE} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 90 | {2CD5A2A6-8865-4D1B-B02E-0BB8E635FF13} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 91 | {CD30D528-82CB-42DA-BA18-4ABCF0A42AE7} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 92 | {E087FCD3-A2BC-409F-9391-F0286D4CD292} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 93 | {3959281A-40A0-4E17-A349-060CFA936C45} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 94 | {F35F90BA-6248-4340-8DB4-E7D3A591EE1F} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 95 | {50F19253-8526-4F9C-BFCD-906C8C3C3DAC} = {8396E2E9-6D1D-45E3-A00C-E351862CAF12} 96 | EndGlobalSection 97 | GlobalSection(ExtensibilityGlobals) = postSolution 98 | SolutionGuid = {E2EB87EB-269D-4A21-8910-5530EB141A0D} 99 | EndGlobalSection 100 | EndGlobal 101 | --------------------------------------------------------------------------------