├── .gitignore ├── .nuget └── packages.config ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── RollbarSharp.sln ├── RollbarSharp.v2.ncrunchsolution └── src ├── RollbarSharp.Mvc4Test ├── App_Start │ ├── FilterConfig.cs │ ├── RouteConfig.cs │ └── WebApiConfig.cs ├── Controllers │ └── MainController.cs ├── Global.asax ├── Global.asax.cs ├── Properties │ └── AssemblyInfo.cs ├── RollbarSharp.Mvc4Test.csproj ├── RollbarSharp.Mvc4Test.v2.ncrunchproject ├── Views │ ├── Main │ │ └── Home.cshtml │ └── Web.config ├── Web.Debug.config ├── Web.Release.config ├── Web.config └── packages.config ├── RollbarSharp.Tests ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── RollbarClientTest.cs ├── RollbarSharp.Tests.csproj ├── RollbarSharp.Tests.v2.ncrunchproject ├── Serialization │ ├── ExceptionModelTest.cs │ ├── NotifierModelTest.cs │ └── TraceModelTest.cs └── packages.config └── RollbarSharp ├── Builders ├── BodyModelBuilder.cs ├── DataModelBuilder.cs ├── ExceptionModelBuilder.cs ├── FrameModelBuilder.cs ├── NotifierModelBuilder.cs ├── PersonModelBuilder.cs ├── RequestModelBuilder.cs ├── ServerModelBuilder.cs └── TraceChainModelBuilder.cs ├── Configuration.cs ├── IRollbarClient.cs ├── InternalExtensions.cs ├── Properties └── AssemblyInfo.cs ├── RequestCompletedEventArgs.cs ├── RequestStartingEventArgs.cs ├── Result.cs ├── RollbarClient.cs ├── RollbarHttpModule.cs ├── RollbarSharp.csproj ├── RollbarSharp.nuspec ├── RollbarSharp.v2.ncrunchproject ├── Serialization ├── BodyModel.cs ├── DataModel.cs ├── ExceptionBodyModel.cs ├── ExceptionModel.cs ├── FrameModel.cs ├── MessageBodyModel.cs ├── NotifierModel.cs ├── PayloadModel.cs ├── PersonModel.cs ├── RequestModel.cs ├── ServerModel.cs └── TraceModel.cs └── packages.config /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studo 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | *_i.c 42 | *_p.c 43 | *_i.h 44 | *.ilk 45 | *.meta 46 | *.obj 47 | *.pch 48 | *.pdb 49 | *.pgc 50 | *.pgd 51 | *.rsp 52 | *.sbr 53 | *.tlb 54 | *.tli 55 | *.tlh 56 | *.tmp 57 | *.tmp_proj 58 | *.log 59 | *.vspscc 60 | *.vssscc 61 | .builds 62 | *.pidb 63 | *.svclog 64 | *.scc 65 | 66 | # Chutzpah Test files 67 | _Chutzpah* 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | *.cachefile 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | *.vspx 81 | 82 | # TFS 2012 Local Workspace 83 | $tf/ 84 | 85 | # Guidance Automation Toolkit 86 | *.gpState 87 | 88 | # ReSharper is a .NET coding add-in 89 | _ReSharper*/ 90 | *.[Rr]e[Ss]harper 91 | *.DotSettings.user 92 | 93 | # JustCode is a .NET coding addin-in 94 | .JustCode 95 | 96 | # TeamCity is a build add-in 97 | _TeamCity* 98 | 99 | # DotCover is a Code Coverage Tool 100 | *.dotCover 101 | 102 | # NCrunch 103 | _NCrunch_* 104 | .*crunch*.local.xml 105 | 106 | # MightyMoose 107 | *.mm.* 108 | AutoTest.Net/ 109 | 110 | # Web workbench (sass) 111 | .sass-cache/ 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.[Pp]ublish.xml 131 | *.azurePubxml 132 | # TODO: Comment the next line if you want to checkin your web deploy settings 133 | # but database connection strings (with potential passwords) will be unencrypted 134 | *.pubxml 135 | *.publishproj 136 | 137 | # NuGet Packages 138 | *.nupkg 139 | # The packages folder can be ignored because of Package Restore 140 | **/packages/* 141 | # except build/, which is used as an MSBuild target. 142 | !**/packages/build/ 143 | # Uncomment if necessary however generally it will be regenerated when needed 144 | #!**/packages/repositories.config 145 | 146 | # Windows Azure Build Output 147 | csx/ 148 | *.build.csdef 149 | 150 | # Windows Store app package directory 151 | AppPackages/ 152 | 153 | # Others 154 | *.[Cc]ache 155 | ClientBin/ 156 | [Ss]tyle[Cc]op.* 157 | ~$* 158 | *~ 159 | *.dbmdl 160 | *.dbproj.schemaview 161 | *.pfx 162 | *.publishsettings 163 | node_modules/ 164 | bower_components/ 165 | 166 | # RIA/Silverlight projects 167 | Generated_Code/ 168 | 169 | # Backup & report files from converting an old project file 170 | # to a newer Visual Studio version. Backup files are not needed, 171 | # because we have git ;-) 172 | _UpgradeReport_Files/ 173 | Backup*/ 174 | UpgradeLog*.XML 175 | UpgradeLog*.htm 176 | 177 | # SQL Server files 178 | *.mdf 179 | *.ldf 180 | 181 | # Business Intelligence projects 182 | *.rdl.data 183 | *.bim.layout 184 | *.bim_*.settings 185 | 186 | # Microsoft Fakes 187 | FakesAssemblies/ 188 | 189 | # Node.js Tools for Visual Studio 190 | .ntvs_analysis.dat 191 | 192 | # Visual Studio 6 build log 193 | *.plg 194 | 195 | # Visual Studio 6 workspace options file 196 | *.opt 197 | -------------------------------------------------------------------------------- /.nuget/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.2.0 (2015-02-27) 2 | 3 | * Capture IP address of application sending report 4 | * Added support for sending innerexceptions to Rollbar 5 | * Add code_version field for Rollbar resolutions 6 | * added userParam for callbacks 7 | 8 | 9 | ## 0.3.1.0 (2013-12-14) 10 | 11 | * Added 'Context' field to the data model 12 | 13 | 14 | ## 0.3.0.0 (2013-12-06) 15 | 16 | * Add Session data to report. Scrub sensitive param values. 17 | * Tidying-up 18 | 19 | 20 | ## 0.2.2.0 (2013-11-26) 21 | 22 | * Fixed: Handle null Response in WebException 23 | 24 | 25 | ## 0.2.1.0 (2013-10-07) 26 | 27 | * Merge pull request #5 from richardversluis/master 28 | * exclude posible null key when converting NameValueCollection to dict 29 | 30 | 31 | ## 0.2.0.0 (2013-10-07) 32 | 33 | * Added a HttpModule which can be used to catch exceptions 34 | 35 | 36 | ## 0.1.7.0 (2013-09-16) 37 | 38 | * Added 'test' rake task to run nuspec 39 | * Parse X-Forwarded-For header for the last IP address for the User IP 40 | * Added support for the git SHA and overloads for custom data model on sends 41 | * Add support for configuring Rollbar from the NLog target and using formatting 42 | 43 | 44 | ## 0.1.6.0 (2013-05-15) 45 | 46 | * Solved threading problem. 47 | * When an X-Forwarded-For HTTP header exists, use that as the user's IP address rather than REMOTE_ADDR. When a user is behind a proxy server or load balancer, X-Forwarded-For will be their actual IP address. 48 | * Simplified the exception filter example 49 | * Removed testing key from config 50 | 51 | 52 | ## 0.1.5.0 (2013-04-26) 53 | 54 | * Added properties 'machine' and 'software' to the 'server' model. These aren't offically supported but they show up on the web and they're useful. 55 | * Changed Custom from an object to Dictionary. 56 | * Now automatically copying the Exception.Data dictionary to Custom['exception_data']. 57 | * Renamed RollbarClient.DataBuilder to NoticeBuilder. A more friendly name, I think 58 | * For text noticed, changed dictionary key type from 'string' to 'object' to make it easier to use 59 | * Dump server vars in MVC test. Add custom data to the exception we raise. 60 | 61 | 62 | ## 0.1.4.0 (2013-04-24) 63 | 64 | * Added RequestStarting event to RollbarClient so you can log the JSON posted to Rollbar 65 | 66 | 67 | ## 0.1.3.0 (2013-04-24) 68 | 69 | * Include "input type=file" elements in the POST parameters collection 70 | 71 | 72 | ## 0.1.2.0 (2013-04-23) 73 | 74 | * Fixed json.net dependency version 75 | 76 | 77 | ## 0.1.1.0 (2013-04-23) 78 | 79 | * Added web.config transform 80 | * Ignore null appsetting values 81 | 82 | 83 | ## 0.1.0.0 (2013-04-23) 84 | 85 | * Initial release. Testing out nuget 86 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. 30 | 31 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 32 | 33 | 3. Grant of Patent License. 34 | 35 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 36 | 37 | 4. Redistribution. 38 | 39 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 40 | 41 | You must give any other recipients of the Work or Derivative Works a copy of this License; and 42 | You must cause any modified files to carry prominent notices stating that You changed the files; and 43 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 44 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 45 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 46 | 47 | 5. Submission of Contributions. 48 | 49 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 50 | 51 | 6. Trademarks. 52 | 53 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 54 | 55 | 7. Disclaimer of Warranty. 56 | 57 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 58 | 59 | 8. Limitation of Liability. 60 | 61 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 62 | 63 | 9. Accepting Warranty or Additional Liability. 64 | 65 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 66 | 67 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NOTE: No longer in active development 2 | 3 | The Rollbar team has done an excellent job creating an official .NET client over at https://github.com/rollbar/Rollbar.NET. It's recommened to use this for new projects and to migrate existing projects to the client. This project is no longer maintained. Thanks to everyone who contributed over the life of this project. 4 | 5 | # RollbarSharp 6 | 7 | [![Build status](https://ci.appveyor.com/api/projects/status/m8wevja31t9fh2i3?svg=true)](https://ci.appveyor.com/project/AlbertoMonteiro/rollbarsharp) 8 | [![NuGet version](http://img.shields.io/nuget/v/Rollbarsharp.svg)](http://www.nuget.org/packages/RollbarSharp/) 9 | [![Nuget downloads](http://img.shields.io/nuget/dt/Rollbarsharp.svg)](http://www.nuget.org/packages/RollbarSharp/) 10 | [![Coverage Status](https://coveralls.io/repos/mroach/RollbarSharp/badge.svg?branch=master&service=github)](https://coveralls.io/github/mroach/RollbarSharp?branch=master) 11 | 12 | 13 | .NET bindings for [Rollbar](http://www.rollbar.com). 14 | 15 | I'm not affiliated with Rollbar, I just like their service. 16 | 17 | Minimum version is .NET 4.5. There's also a dependency on `System.Web.Routing`, so you'll at least need ASP.NET MVC installed on the system. 18 | 19 | ## Installation 20 | 21 | RollbarSharp is available on [Nuget](https://nuget.org/packages/RollbarSharp/) and can be installed by: 22 | 23 | ``` 24 | PM> Install-Package RollbarSharp 25 | ``` 26 | 27 | ## Usage 28 | 29 | ### Configuration 30 | 31 | The easiest way to get going is to add the `Rollbar.AccessToken` item to your app settings. 32 | 33 | ```xml 34 | 35 | 36 | 37 | 38 | 39 | 40 | ``` 41 | 42 | From there, you have several options on how to integrate with your app. 43 | 44 | ### As an ASP.NET Filter 45 | 46 | ```csharp 47 | public class RollbarExceptionFilter : IExceptionFilter 48 | { 49 | public void OnException(ExceptionContext filterContext) 50 | { 51 | if (filterContext.ExceptionHandled) 52 | return; 53 | 54 | (new RollbarClient()).SendException(filterContext.Exception); 55 | } 56 | } 57 | ``` 58 | 59 | And then in `Global.asax.cs` you can do 60 | 61 | ```csharp 62 | GlobalFilters.Filters.Add(new RollbarExceptionFilter()); 63 | ``` 64 | 65 | Or if you're using an inversion of control system that supports binding filters, you could do it there. This is an example with [Ninject](http://www.ninject.org/). You could even dependency-inject the `RollbarClient` if you want to create it in your own factory method. 66 | 67 | ```csharp 68 | kernel.BindFilter(FilterScope.Global, 10).InSingletonScope(); 69 | ``` 70 | 71 | The `OnException` method could instead be used verbatim inside a `Controller` if you add the `override` keyword. `protected override void OnException(ExceptionContext filterContext) ...` 72 | 73 | 74 | ### As an ASP.NET application event handler (Global.asax.cs) 75 | 76 | ```csharp 77 | protected void Application_Error(object sender, EventArgs e) 78 | { 79 | var exception = Server.GetLastError().GetBaseException(); 80 | 81 | (new RollbarClient()).SendException(exception); 82 | } 83 | ``` 84 | 85 | 86 | ### As an HttpModule in the Web.config 87 | 88 | #### IIS Integrated Pipeline 89 | 90 | ```xml 91 | 92 | 93 | 94 | 95 | 96 | ``` 97 | 98 | #### IIS Classic Pipeline 99 | 100 | ```xml 101 | 102 | 103 | 104 | 105 | 106 | ``` 107 | 108 | ### As an NLog target 109 | 110 | You'll need to add the [NLog.RollbarSharp](https://github.com/mroach/NLog.RollbarSharp) assembly to your project for this to work but it's available on [NuGet](https://www.nuget.org/packages/NLog.RollbarSharp/). Check out [the NLog.RollbarSharp README](https://github.com/mroach/NLog.RollbarSharp/blob/master/README.md) for configuration details, but here's the skinny: 111 | 112 | ```xml 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | ``` 129 | 130 | ## Bugs 131 | 132 | * If you encounter a bug, performance issue, or malfunction, please add an [Issue](https://github.com/mroach/rollbarsharp/issues) with steps on how to reproduce the problem. 133 | 134 | 135 | ## Building 136 | 137 | I'm using [ScriptCs](http://scriptcs.net/) for managing the build process. 138 | 139 | To build go to **build** folder and then run this command: 140 | 141 | ``` 142 | scriptcs -script build.csx 143 | ``` 144 | 145 | After that, upload new **RollbarSharp.{version}.nupkg** to nuget. 146 | 147 | ## TODO 148 | 149 | * Add more tests 150 | -------------------------------------------------------------------------------- /RollbarSharp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RollbarSharp", "src\RollbarSharp\RollbarSharp.csproj", "{43A8B009-CA64-4D25-845A-FE2A53890FBC}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RollbarSharp.Tests", "src\RollbarSharp.Tests\RollbarSharp.Tests.csproj", "{898D9D95-D956-4284-82D5-6BFDBFDE14EB}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RollbarSharp.Mvc4Test", "src\RollbarSharp.Mvc4Test\RollbarSharp.Mvc4Test.csproj", "{18636614-E998-4A78-86A4-37BFA9300F8E}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {43A8B009-CA64-4D25-845A-FE2A53890FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {43A8B009-CA64-4D25-845A-FE2A53890FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {43A8B009-CA64-4D25-845A-FE2A53890FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {43A8B009-CA64-4D25-845A-FE2A53890FBC}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {898D9D95-D956-4284-82D5-6BFDBFDE14EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {898D9D95-D956-4284-82D5-6BFDBFDE14EB}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {898D9D95-D956-4284-82D5-6BFDBFDE14EB}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {898D9D95-D956-4284-82D5-6BFDBFDE14EB}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {18636614-E998-4A78-86A4-37BFA9300F8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {18636614-E998-4A78-86A4-37BFA9300F8E}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {18636614-E998-4A78-86A4-37BFA9300F8E}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {18636614-E998-4A78-86A4-37BFA9300F8E}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /RollbarSharp.v2.ncrunchsolution: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | false 4 | true 5 | true 6 | UseDynamicAnalysis 7 | UseStaticAnalysis 8 | UseStaticAnalysis 9 | UseStaticAnalysis 10 | UseStaticAnalysis 11 | 12 | RollbarSharp.Mvc4Test\RollbarSharp.Mvc4Test.csproj 13 | RollbarSharp.Tests\RollbarSharp.Tests.csproj 14 | 15 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Web.Mvc; 3 | 4 | namespace RollbarSharp.Mvc4Test 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new RollbarExceptionFilter()); 11 | filters.Add(new HandleErrorAttribute()); 12 | } 13 | } 14 | 15 | public class RollbarExceptionFilter : IExceptionFilter 16 | { 17 | public void OnException(ExceptionContext filterContext) 18 | { 19 | if (filterContext.ExceptionHandled) 20 | return; 21 | 22 | (new RollbarClient()).SendException(filterContext.Exception, modelAction: m => m.Context = "error#context"); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace RollbarSharp.Mvc4Test 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Http; 5 | 6 | namespace RollbarSharp.Mvc4Test 7 | { 8 | public static class WebApiConfig 9 | { 10 | public static void Register(HttpConfiguration config) 11 | { 12 | config.Routes.MapHttpRoute( 13 | name: "DefaultApi", 14 | routeTemplate: "api/{controller}/{id}", 15 | defaults: new { id = RouteParameter.Optional } 16 | ); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Controllers/MainController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Mvc; 5 | using System.Web.Security; 6 | 7 | namespace RollbarSharp.Mvc4Test.Controllers 8 | { 9 | public class MainController : Controller 10 | { 11 | public ActionResult Home() 12 | { 13 | FormsAuthentication.SetAuthCookie("mroach", true); 14 | 15 | Session["UserId"] = 102; 16 | Session["CartAmount"] = 123.45m; 17 | Session["Username"] = "mroach"; 18 | Session["CartItems"] = new[] { 233, 479073, 2323, 9923 }; 19 | Session["Userdata"] = new HashSet(); 20 | Session["Password"] = "y u store password?"; 21 | Session["Secret"] = "A23A854F3DD64CC9BEC6D498A2C097D8"; 22 | Session["secret"] = "another secret :o"; 23 | 24 | var vars = Request.ServerVariables.AllKeys.Select(k => k + " => " + Request.ServerVariables[k]); 25 | 26 | ViewBag.Vars = string.Join("\n", vars); 27 | 28 | return View(); 29 | } 30 | 31 | public ActionResult Error() 32 | { 33 | var ex = new Exception("An error has occurred upon request"); 34 | ex.Data["arbitrary_data"] = DateTime.UtcNow; 35 | throw ex; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="RollbarSharp.Mvc4Test.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | 5 | namespace RollbarSharp.Mvc4Test 6 | { 7 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 8 | // visit http://go.microsoft.com/?LinkId=9394801 9 | public class MvcApplication : System.Web.HttpApplication 10 | { 11 | protected void Application_Start() 12 | { 13 | AreaRegistration.RegisterAllAreas(); 14 | 15 | WebApiConfig.Register(GlobalConfiguration.Configuration); 16 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RollbarSharp.Mvc4Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RollbarSharp.Mvc4Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("37888abd-6a2b-4776-a2a7-6273a55eef79")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/RollbarSharp.Mvc4Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {18636614-E998-4A78-86A4-37BFA9300F8E} 11 | {E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | RollbarSharp.Mvc4Test 15 | RollbarSharp.Mvc4Test 16 | v4.5 17 | false 18 | false 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | true 28 | full 29 | false 30 | bin\ 31 | DEBUG;TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | pdbonly 38 | true 39 | bin\ 40 | TRACE 41 | prompt 42 | 4 43 | false 44 | 45 | 46 | 47 | 48 | ..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 49 | True 50 | 51 | 52 | ..\..\packages\Newtonsoft.Json.5.0.1\lib\net45\Newtonsoft.Json.dll 53 | True 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ..\..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll 66 | True 67 | 68 | 69 | ..\..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll 70 | True 71 | 72 | 73 | ..\..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll 74 | True 75 | 76 | 77 | ..\..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll 78 | True 79 | 80 | 81 | ..\..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll 82 | True 83 | 84 | 85 | ..\..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll 86 | True 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | True 97 | ..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.dll 98 | 99 | 100 | ..\packages\Microsoft.AspNet.WebApi.Client.4.0.20710.0\lib\net40\System.Net.Http.Formatting.dll 101 | 102 | 103 | True 104 | ..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.WebRequest.dll 105 | 106 | 107 | ..\packages\Microsoft.AspNet.WebApi.Core.4.0.20710.0\lib\net40\System.Web.Http.dll 108 | 109 | 110 | ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.20710.0\lib\net40\System.Web.Http.WebHost.dll 111 | 112 | 113 | 114 | ..\RollbarSharp\bin\$(Configuration)\RollbarSharp.dll 115 | 116 | 117 | 118 | 119 | 120 | 121 | Global.asax 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | Web.config 133 | 134 | 135 | Web.config 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | {43a8b009-ca64-4d25-845a-fe2a53890fbc} 148 | RollbarSharp 149 | 150 | 151 | 152 | 153 | 154 | 155 | 10.0 156 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | False 169 | True 170 | 51558 171 | / 172 | 173 | 174 | False 175 | False 176 | 177 | 178 | False 179 | 180 | 181 | 182 | 183 | 189 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/RollbarSharp.Mvc4Test.v2.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | 1000 3 | false 4 | false 5 | false 6 | true 7 | false 8 | false 9 | false 10 | false 11 | false 12 | true 13 | true 14 | false 15 | true 16 | true 17 | true 18 | 60000 19 | 20 | 21 | 22 | AutoDetect 23 | STA 24 | x86 25 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Views/Main/Home.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Index"; 3 | } 4 | 5 |

Index

6 | 7 |

Welcome, @User.Identity.Name

8 | 9 |
@ViewBag.Vars
-------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/RollbarSharp.Mvc4Test/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RollbarSharp.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RollbarSharp.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("995de97c-1e1d-45ae-a52e-8558f5b04502")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/RollbarClientTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using NUnit.Framework; 7 | using RollbarSharp.Builders; 8 | 9 | namespace RollbarSharp.Tests 10 | { 11 | [TestFixture] 12 | public class RollbarClientTest 13 | { 14 | [Test] 15 | public void when_serializing_message_notice_result_should_not_be_empty() 16 | { 17 | var client = new RollbarClient(); 18 | var notice = client.NoticeBuilder.CreateMessageNotice("Hello"); 19 | 20 | notice.Server.Host = "miker"; 21 | notice.Request.Url = "http://localhost/hej"; 22 | notice.Request.Method = "GET"; 23 | 24 | var serialized = client.Serialize(notice); 25 | 26 | Assert.IsNotNullOrEmpty(serialized); 27 | } 28 | 29 | [Test] 30 | public void when_serializing_exception_notice_result_should_not_be_empty() 31 | { 32 | var client = new RollbarClient(); 33 | Exception exception = new NotImplementedException(); 34 | 35 | var notice = client.NoticeBuilder.CreateExceptionNotice(exception); 36 | notice.Server.Host = "miker"; 37 | notice.Request.Url = "http://localhost/hej"; 38 | notice.Request.Method = "GET"; 39 | notice.Request.Headers.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"); 40 | notice.Request.UserIp = "67.90.39.34"; 41 | notice.Person.Id = "123"; 42 | notice.Person.Username = Environment.UserName; 43 | 44 | var serialized = client.Serialize(notice); 45 | 46 | Assert.IsNotNullOrEmpty(serialized); 47 | } 48 | 49 | [Test] 50 | public void when_calling_send_exception_task_returns_and_can_be_used() 51 | { 52 | var client = new RollbarClient(); 53 | Exception exception = new NotImplementedException(); 54 | 55 | var task = client.SendException(exception); 56 | 57 | Assert.IsNotNull(task); 58 | Assert.DoesNotThrow(() => task.Wait(0)); 59 | } 60 | 61 | [Test] 62 | public void when_calling_send_critical_exception_task_returns_and_can_be_used() 63 | { 64 | var client = new RollbarClient(); 65 | Exception exception = new NotImplementedException(); 66 | 67 | var task = client.SendCriticalException(exception); 68 | 69 | Assert.IsNotNull(task); 70 | Assert.DoesNotThrow(() => task.Wait(0)); 71 | } 72 | 73 | 74 | [Test] 75 | public void when_calling_send_error_exception_task_returns_and_can_be_used() 76 | { 77 | var client = new RollbarClient(); 78 | Exception exception = new NotImplementedException(); 79 | 80 | var task = client.SendErrorException(exception); 81 | 82 | Assert.IsNotNull(task); 83 | Assert.DoesNotThrow(() => task.Wait(0)); 84 | } 85 | 86 | [Test] 87 | public void when_calling_send_warning_exception_task_returns_and_can_be_used() 88 | { 89 | var client = new RollbarClient(); 90 | Exception exception = new NotImplementedException(); 91 | 92 | var task = client.SendWarningException(exception); 93 | 94 | Assert.IsNotNull(task); 95 | Assert.DoesNotThrow(() => task.Wait(0)); 96 | } 97 | 98 | [Test] 99 | public void when_calling_send_critical_message_task_returns_and_can_be_used() 100 | { 101 | var client = new RollbarClient(); 102 | var message = ""; 103 | 104 | var task = client.SendCriticalMessage(message); 105 | 106 | Assert.IsNotNull(task); 107 | Assert.DoesNotThrow(() => task.Wait(0)); 108 | } 109 | 110 | [Test] 111 | public void when_calling_send_error_message_task_returns_and_can_be_used() 112 | { 113 | var client = new RollbarClient(); 114 | var message = ""; 115 | 116 | var task = client.SendErrorMessage(message); 117 | 118 | Assert.IsNotNull(task); 119 | Assert.DoesNotThrow(() => task.Wait(0)); 120 | } 121 | 122 | [Test] 123 | public void when_calling_send_warning_message_task_returns_and_can_be_used() 124 | { 125 | var client = new RollbarClient(); 126 | var message = ""; 127 | 128 | var task = client.SendWarningMessage(message); 129 | 130 | Assert.IsNotNull(task); 131 | Assert.DoesNotThrow(() => task.Wait(0)); 132 | } 133 | 134 | [Test] 135 | public void when_calling_send_info_message_task_returns_and_can_be_used() 136 | { 137 | var client = new RollbarClient(); 138 | var message = ""; 139 | 140 | var task = client.SendInfoMessage(message); 141 | 142 | Assert.IsNotNull(task); 143 | Assert.DoesNotThrow(() => task.Wait(0)); 144 | } 145 | 146 | [Test] 147 | public void when_calling_send_debug_message_task_returns_and_can_be_used() 148 | { 149 | var client = new RollbarClient(); 150 | var message = ""; 151 | 152 | var task = client.SendDebugMessage(message); 153 | 154 | Assert.IsNotNull(task); 155 | Assert.DoesNotThrow(() => task.Wait(0)); 156 | } 157 | 158 | [Test] 159 | public void when_calling_send_message_task_returns_and_can_be_used() 160 | { 161 | var client = new RollbarClient(); 162 | var message = ""; 163 | 164 | var task = client.SendMessage(message, "info"); 165 | 166 | Assert.IsNotNull(task); 167 | Assert.DoesNotThrow(() => task.Wait(0)); 168 | } 169 | 170 | [Test] 171 | public void when_calling_send_task_returns_and_can_be_used() 172 | { 173 | var client = new RollbarClient(); 174 | var message = ""; 175 | 176 | var notice = new DataModelBuilder().CreateMessageNotice(message, "debug"); 177 | 178 | var task = client.Send(notice, null); 179 | 180 | Assert.IsNotNull(task); 181 | Assert.DoesNotThrow(() => task.Wait(0)); 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/RollbarSharp.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {898D9D95-D956-4284-82D5-6BFDBFDE14EB} 8 | Library 9 | Properties 10 | RollbarSharp.Tests 11 | RollbarSharp.Tests 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | ..\..\packages\NUnit.2.6.2\lib\nunit.framework.dll 39 | True 40 | 41 | 42 | ..\RollbarSharp\bin\$(Configuration)\RollbarSharp.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Code 52 | 53 | 54 | Code 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | {43a8b009-ca64-4d25-845a-fe2a53890fbc} 65 | RollbarSharp 66 | 67 | 68 | 69 | 76 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/RollbarSharp.Tests.v2.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | 1000 3 | false 4 | false 5 | false 6 | true 7 | false 8 | false 9 | false 10 | false 11 | false 12 | true 13 | true 14 | false 15 | true 16 | true 17 | true 18 | 60000 19 | 20 | 21 | 22 | AutoDetect 23 | STA 24 | x86 25 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/Serialization/ExceptionModelTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using RollbarSharp.Builders; 4 | 5 | namespace RollbarSharp.Tests.Serialization 6 | { 7 | [TestFixture] 8 | public class ExceptionModelTest 9 | { 10 | [Test] 11 | public void when_creating_from_manually_created_exception_should_have_expected_Class() 12 | { 13 | var ex = new InvalidOperationException("Invalid operation"); 14 | var model = ExceptionModelBuilder.CreateFromException(ex); 15 | 16 | Assert.AreEqual(typeof(InvalidOperationException).Name, model.Class); 17 | } 18 | 19 | [Test] 20 | public void when_creating_from_manually_created_exception_should_have_Message_copied() 21 | { 22 | var ex = new InvalidOperationException("Invalid operation"); 23 | var model = ExceptionModelBuilder.CreateFromException(ex); 24 | 25 | Assert.AreEqual("Invalid operation", model.Message); 26 | } 27 | 28 | [Test] 29 | public void when_creating_from_thrown_exception_should_have_expected_Class() 30 | { 31 | try 32 | { 33 | CreateException(); 34 | } 35 | catch (Exception ex) 36 | { 37 | var model = ExceptionModelBuilder.CreateFromException(ex); 38 | 39 | Assert.AreEqual(typeof(DivideByZeroException).Name, model.Class); 40 | } 41 | } 42 | 43 | [Test] 44 | public void when_creating_from_thrown_exception_should_have_Message() 45 | { 46 | try 47 | { 48 | CreateException(); 49 | } 50 | catch (Exception ex) 51 | { 52 | var model = ExceptionModelBuilder.CreateFromException(ex); 53 | 54 | Assert.IsNotNullOrEmpty(model.Message); 55 | } 56 | } 57 | 58 | private int CreateException() 59 | { 60 | var x = 0; 61 | var y = 1 / x; 62 | return y; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/Serialization/NotifierModelTest.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using NUnit.Framework; 3 | using RollbarSharp.Builders; 4 | using RollbarSharp.Serialization; 5 | 6 | namespace RollbarSharp.Tests.Serialization 7 | { 8 | [TestFixture] 9 | public class NotifierModelTest 10 | { 11 | NotifierModel model; 12 | 13 | [SetUp] 14 | public void SetUp() 15 | { 16 | model = NotifierModelBuilder.CreateFromAssemblyInfo(); 17 | } 18 | 19 | [Test] 20 | public void when_creating_notifier_from_assembly_info_should_have_RollbarSharp_for_Name() 21 | { 22 | Assert.AreEqual("RollbarSharp", model.Name); 23 | } 24 | 25 | [Test] 26 | public void when_creating_notifier_from_assembly_info_should_have_Version_populated() 27 | { 28 | Assert.IsNotNullOrEmpty(model.Version); 29 | } 30 | 31 | [Test] 32 | public void when_creating_notifier_from_assembly_info_Version_should_match_assembly_version() 33 | { 34 | var expectedVersion = Assembly.GetAssembly(typeof(NotifierModel)).GetName(); 35 | 36 | Assert.AreEqual(expectedVersion.Version.ToString(), model.Version); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/Serialization/TraceModelTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using NUnit.Framework; 4 | using RollbarSharp.Builders; 5 | using System.Reflection; 6 | 7 | namespace RollbarSharp.Tests.Serialization 8 | { 9 | [TestFixture] 10 | public class TraceModelTest 11 | { 12 | [Test] 13 | public void when_creating_from_thrown_exception_should_have_frames() 14 | { 15 | try 16 | { 17 | GenerateException(null); 18 | } 19 | catch (Exception ex) 20 | { 21 | var model = TraceChainModelBuilder.CreateFromException(ex).FirstOrDefault(); 22 | Assert.IsNotNull(model.Frames); 23 | } 24 | } 25 | 26 | [Test] 27 | public void when_creating_from_thrown_exception_should_have_more_than_0_frames() 28 | { 29 | try 30 | { 31 | GenerateException(null); 32 | } 33 | catch (Exception ex) 34 | { 35 | var model = TraceChainModelBuilder.CreateFromException(ex).FirstOrDefault(); 36 | Assert.Greater(model.Frames.Length, 0); 37 | } 38 | } 39 | 40 | [Test] 41 | public void when_creating_from_thrown_exception_should_have_Exception_model() 42 | { 43 | try 44 | { 45 | GenerateException(null); 46 | } 47 | catch (Exception ex) 48 | { 49 | var model = TraceChainModelBuilder.CreateFromException(ex).FirstOrDefault(); 50 | Assert.IsNotNull(model.Exception); 51 | } 52 | } 53 | 54 | [Test()] 55 | public void when_creating_from_thrown_within_reflection_call_exception_should_have_Exception_model() 56 | { 57 | var method = this.GetType().GetMethod("MethodWithException"); 58 | try 59 | { 60 | method.Invoke(this, new object[]{ null }); 61 | Assert.Fail("The previous call must throw an exception"); 62 | } 63 | catch (Exception ex) 64 | { 65 | var model = TraceChainModelBuilder.CreateFromException(ex).FirstOrDefault(); 66 | Assert.IsNotNull(model.Exception); 67 | } 68 | } 69 | 70 | private int GenerateException(string noparam) 71 | { 72 | var x = 0; 73 | var q = 1 / x; 74 | return q; 75 | } 76 | 77 | public void MethodWithException(string noparam) 78 | { 79 | throw new ArgumentException("Test exception"); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/RollbarSharp.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/BodyModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using RollbarSharp.Serialization; 4 | 5 | namespace RollbarSharp.Builders 6 | { 7 | /// 8 | /// Builder for the 'body' of the request. 9 | /// This will be either an exception with details 10 | /// or a plain text message with optional fields 11 | /// 12 | public static class BodyModelBuilder 13 | { 14 | public static ExceptionBodyModel CreateExceptionBody(Exception exception) 15 | { 16 | var traces = TraceChainModelBuilder.CreateFromException(exception); 17 | return new ExceptionBodyModel(traces); 18 | } 19 | 20 | public static MessageBodyModel CreateMessageBody(string message, IDictionary customData) 21 | { 22 | return new MessageBodyModel(message, customData); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/DataModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.Web; 7 | using RollbarSharp.Serialization; 8 | 9 | namespace RollbarSharp.Builders 10 | { 11 | public class DataModelBuilder 12 | { 13 | public Configuration Configuration { get; protected set; } 14 | 15 | public DataModelBuilder() 16 | :this(Configuration.CreateFromAppConfig()) 17 | { 18 | } 19 | 20 | public DataModelBuilder(Configuration configuration) 21 | { 22 | Configuration = configuration; 23 | } 24 | 25 | public DataModel CreateExceptionNotice(Exception ex, string message = null, string level = "error") 26 | { 27 | var body = BodyModelBuilder.CreateExceptionBody(ex); 28 | var model = Create(level, body); 29 | 30 | //merge exception data dictionaries to list of keyValues pairs 31 | var keyValuePairs = body.TraceChain.Where(tm => tm.Exception.Data != null).SelectMany(tm => tm.Exception.Data); 32 | 33 | foreach (var keyValue in keyValuePairs) 34 | { 35 | //the keys in keyValuePairs aren't necessarily unique, so don't add but overwrite 36 | model.Custom[keyValue.Key.ToString()] = keyValue.Value; 37 | } 38 | 39 | model.Title = message; 40 | 41 | return model; 42 | } 43 | 44 | public DataModel CreateMessageNotice(string message, string level = "info", IDictionary customData = null) 45 | { 46 | return Create(level, BodyModelBuilder.CreateMessageBody(message, customData)); 47 | } 48 | 49 | /// 50 | /// Create the best stub of a request that we can using the message level and body 51 | /// 52 | /// 53 | /// 54 | /// 55 | protected DataModel Create(string level, BodyModel body) 56 | { 57 | var model = new DataModel(level, body); 58 | 59 | model.CodeVersion = Configuration.CodeVersion; 60 | model.Environment = Configuration.Environment; 61 | model.Platform = Configuration.Platform; 62 | model.Language = Configuration.Language; 63 | model.Framework = Configuration.Framework; 64 | 65 | model.Timestamp = (ulong)Now(); 66 | 67 | model.Notifier = NotifierModelBuilder.CreateFromAssemblyInfo(); 68 | 69 | var currentHttpRequest = GetCurrentHttpRequest(); 70 | 71 | if (currentHttpRequest == null) 72 | { 73 | model.Request = new RequestModel(); 74 | model.Server = new ServerModel(); 75 | 76 | //Obtain person information on non-hosted environment only 77 | model.Person = System.Web.Hosting.HostingEnvironment.IsHosted 78 | ? new PersonModel() 79 | : PersonModelBuilder.CreateFromEnvironment(); 80 | } 81 | else 82 | { 83 | model.Request = RequestModelBuilder.CreateFromHttpRequest(currentHttpRequest, HttpContext.Current.Session, Configuration.ScrubParams); 84 | model.Server = ServerModelBuilder.CreateFromHttpRequest(currentHttpRequest); 85 | model.Person = PersonModelBuilder.CreateFromHttpRequest(currentHttpRequest); 86 | } 87 | 88 | model.Server.GitSha = Configuration.GitSha; 89 | 90 | return model; 91 | } 92 | 93 | /// 94 | /// Returns the current HttpRequest. If not available, returns null 95 | /// 96 | /// 97 | private static HttpRequest GetCurrentHttpRequest() 98 | { 99 | var cx = HttpContext.Current; 100 | HttpRequest req = null; 101 | 102 | if (cx != null) 103 | { 104 | 105 | //In the Application_Start HttpContext.Request is not available. 106 | //Instead of HttpContext.Request returning null, it throws an exception. So we swallow the exception here. 107 | try 108 | { 109 | req = cx.Request; 110 | } 111 | catch (HttpException) 112 | { 113 | 114 | } 115 | 116 | } 117 | 118 | return req; 119 | } 120 | 121 | /// 122 | /// Current UTC date time as a UNIX timestamp 123 | /// 124 | /// 125 | private static double Now() 126 | { 127 | var epoch = new DateTime(1970, 1, 1); 128 | return (DateTime.UtcNow - epoch).TotalSeconds; 129 | } 130 | 131 | public static string FingerprintHash(params object[] fields) 132 | { 133 | return FingerprintHash(string.Join(",", fields)); 134 | } 135 | 136 | /// 137 | /// To make sure fingerprints are the correct length and don't 138 | /// contain any problematic characters, SHA1 the fingerprint. 139 | /// 140 | /// 141 | /// 142 | public static string FingerprintHash(string data) 143 | { 144 | using (var sha = new SHA1Managed()) 145 | { 146 | var bytes = Encoding.UTF8.GetBytes(data); 147 | var hash = sha.ComputeHash(bytes); 148 | return BitConverter.ToString(hash).Replace("-", string.Empty); 149 | } 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/ExceptionModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using RollbarSharp.Serialization; 4 | 5 | namespace RollbarSharp.Builders 6 | { 7 | public static class ExceptionModelBuilder 8 | { 9 | /// 10 | /// Converts an exception to an . 11 | /// 12 | public static ExceptionModel CreateFromException(Exception ex) 13 | { 14 | var m = new ExceptionModel(ex.GetType().Name, ex.Message); 15 | 16 | if (ex.Data.Count > 0) 17 | m.Data = ex.Data.Keys.Cast().ToDictionary(k => k, k => ex.Data[k]); 18 | 19 | return m; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/FrameModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using RollbarSharp.Serialization; 6 | 7 | namespace RollbarSharp.Builders 8 | { 9 | public static class FrameModelBuilder 10 | { 11 | /// 12 | /// Try to include file names in the stack trace rather than just method names with internal offsets 13 | /// 14 | public static bool UseFileNames = true; 15 | 16 | /// 17 | /// Converts the Exception's stack trace to simpler models. 18 | /// 19 | /// 20 | /// 21 | /// If we want to get fancier, we can rip off ideas from 22 | public static FrameModel[] CreateFramesFromException(Exception exception) 23 | { 24 | var lines = new List(); 25 | var stackFrames = new StackTrace(exception, UseFileNames).GetFrames(); 26 | 27 | if (stackFrames == null || stackFrames.Length == 0) 28 | return lines.ToArray(); 29 | 30 | foreach (var frame in stackFrames) 31 | { 32 | var method = frame.GetMethod(); 33 | var lineNumber = frame.GetFileLineNumber(); 34 | var fileName = frame.GetFileName(); 35 | 36 | // when the line number is zero, you can try using the IL offset 37 | if (lineNumber == 0) 38 | lineNumber = frame.GetILOffset(); 39 | 40 | if (lineNumber == -1) 41 | lineNumber = frame.GetNativeOffset(); 42 | 43 | // line numbers less than 0 are not accepted 44 | if (lineNumber < 0) 45 | lineNumber = 0; 46 | 47 | string methodName; 48 | 49 | //At least on Mono 4.2.1: on reflection call frame.GetMethod() can be null 50 | if (method != null) 51 | { 52 | // file names aren't always available, so use the type name instead, if possible 53 | if (string.IsNullOrEmpty(fileName)) 54 | { 55 | fileName = method.ReflectedType != null 56 | ? method.ReflectedType.FullName 57 | : "(unknown)"; 58 | } 59 | 60 | methodName = method.Name; 61 | 62 | // add method parameters to the method name. helpful for resolving overloads. 63 | var methodParams = method.GetParameters(); 64 | if (methodParams.Length > 0) 65 | { 66 | var paramDesc = string.Join(", ", methodParams.Select(p => p.ParameterType + " " + p.Name)); 67 | methodName = methodName + "(" + paramDesc + ")"; 68 | } 69 | } 70 | else 71 | { 72 | methodName = "(unknown)"; 73 | } 74 | 75 | lines.Add(new FrameModel(fileName, lineNumber, methodName)); 76 | } 77 | 78 | return lines.ToArray(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/NotifierModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using RollbarSharp.Serialization; 3 | 4 | namespace RollbarSharp.Builders 5 | { 6 | public static class NotifierModelBuilder 7 | { 8 | /// 9 | /// Creates a model representing this notifier binding itself. 10 | /// Will be reported as the assembly's name and currently compiled version. 11 | /// 12 | /// 13 | public static NotifierModel CreateFromAssemblyInfo() 14 | { 15 | var ai = Assembly.GetAssembly(typeof(NotifierModel)).GetName(); 16 | 17 | return new NotifierModel(ai.Name, ai.Version.ToString()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/PersonModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using RollbarSharp.Serialization; 3 | using System; 4 | 5 | namespace RollbarSharp.Builders 6 | { 7 | public class PersonModelBuilder 8 | { 9 | /// 10 | /// Find just the username from server vars: AUTH_USER, LOGON_USER, REMOTE_USER 11 | /// Sets both the ID and Username to this username since ID is required. 12 | /// Email address won't be set. 13 | /// 14 | /// 15 | /// 16 | public static PersonModel CreateFromHttpRequest(HttpRequest request) 17 | { 18 | var username = request.ServerVariables["AUTH_USER"] ?? 19 | request.ServerVariables["LOGON_USER"] ?? 20 | request.ServerVariables["REMOTE_USER"]; 21 | 22 | return new PersonModel {Id = username, Username = username}; 23 | } 24 | 25 | /// 26 | /// Find just the username from environment. 27 | /// Sets both the ID and Username to this username since ID is required. 28 | /// Email address won't be set. 29 | /// 30 | /// 31 | public static PersonModel CreateFromEnvironment() 32 | { 33 | //Make the user-id as unique but reproducible as possible (a SID would be even better, but that might be a security risk) 34 | var id = string.Format(@"{0}\{1}", Environment.MachineName,Environment.UserName); 35 | 36 | if (id.Length > 40) { 37 | id = id.Substring(0, 40); 38 | } 39 | 40 | return new PersonModel { 41 | Id = id, 42 | Username = Environment.UserName }; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/RequestModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.SessionState; 6 | using RollbarSharp.Serialization; 7 | 8 | namespace RollbarSharp.Builders 9 | { 10 | public static class RequestModelBuilder 11 | { 12 | /// 13 | /// Converts a standard to a 14 | /// Copies over: URL, HTTP method, HTTP headers, query string params, POST params, user IP, route params 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | public static RequestModel CreateFromHttpRequest(HttpRequest request, HttpSessionState session, string[] scrubParams = null) 21 | { 22 | var m = new RequestModel(); 23 | 24 | m.Url = request.Url.ToString(); 25 | m.Method = request.HttpMethod; 26 | m.Headers = request.Headers.ToDictionary(); 27 | m.Session = session.ToDictionary(); 28 | 29 | m.QueryStringParameters = request.QueryString.ToDictionary(); 30 | m.PostParameters = request.Unvalidated.Form.ToDictionary(); 31 | 32 | // add posted files to the post collection 33 | try 34 | { 35 | if (request.Files.Count > 0) 36 | foreach (var file in request.Files.Describe()) 37 | m.PostParameters.Add(file.Key, "FILE: " + file.Value); 38 | } 39 | catch (HttpException) 40 | { 41 | // Files from request could not be read here because they are streamed 42 | // and have been read earlier by e.g. WCF Rest Service or Open RIA Services 43 | } 44 | 45 | // if the X-Forwarded-For header exists, use that as the user's IP. 46 | // that will be the true remote IP of a user behind a proxy server or load balancer 47 | m.UserIp = IpFromXForwardedFor(request) ?? request.UserHostAddress; 48 | 49 | m.Parameters = request.RequestContext.RouteData.Values.ToDictionary(v => v.Key, v => v.Describe()); 50 | 51 | if (scrubParams != null) 52 | { 53 | m.Headers = Scrub(m.Headers, scrubParams); 54 | m.Session = Scrub(m.Session, scrubParams); 55 | m.QueryStringParameters = Scrub(m.QueryStringParameters, scrubParams); 56 | m.PostParameters = Scrub(m.PostParameters, scrubParams); 57 | } 58 | 59 | return m; 60 | } 61 | 62 | // X-Forwarded-For header, if populated, contains a comma separated list of ip address 63 | // of each successive proxy server. Take the last or most reliable IP address if there 64 | // are multiple addresses. 65 | private static string IpFromXForwardedFor(HttpRequest request) 66 | { 67 | var forwardedFor = request.Headers["X-Forwarded-For"]; 68 | if (!string.IsNullOrEmpty(forwardedFor) && forwardedFor.Contains(",")) 69 | { 70 | forwardedFor = forwardedFor.Split(',').Last().Trim(); 71 | } 72 | return forwardedFor; 73 | } 74 | 75 | /// 76 | /// Finds dictionary keys in the list and replaces their values 77 | /// with asterisks. Key comparison is case insensitive. 78 | /// 79 | /// 80 | /// 81 | /// 82 | private static IDictionary Scrub(IDictionary dict, string[] scrubParams) 83 | { 84 | if (dict == null || !dict.Any()) 85 | return dict; 86 | 87 | if (scrubParams == null || !scrubParams.Any()) 88 | return dict; 89 | 90 | var itemsToUpdate = dict.Keys 91 | .Where(k => scrubParams.Contains(k, StringComparer.InvariantCultureIgnoreCase)) 92 | .ToArray(); 93 | 94 | if (itemsToUpdate.Any()) 95 | { 96 | foreach (var key in itemsToUpdate) 97 | { 98 | var len = dict[key] == null ? 8 : dict[key].Length; 99 | dict[key] = new string('*', len); 100 | } 101 | } 102 | 103 | return dict; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/ServerModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | using RollbarSharp.Serialization; 4 | 5 | namespace RollbarSharp.Builders 6 | { 7 | public static class ServerModelBuilder 8 | { 9 | /// 10 | /// Creates a using data from the given 11 | /// . Finds: HTTP Host, Server Name, Application Physical Path 12 | /// 13 | /// 14 | /// 15 | public static ServerModel CreateFromHttpRequest(HttpRequest request) 16 | { 17 | var host = request.ServerVariables.Get("HTTP_HOST"); 18 | 19 | if (string.IsNullOrEmpty(host)) 20 | host = request.ServerVariables.Get("SERVER_NAME"); 21 | 22 | var root = request.ServerVariables.Get("APPL_PHYSICAL_PATH"); 23 | 24 | if (string.IsNullOrEmpty(root)) 25 | root = HttpRuntime.AppDomainAppPath ?? Environment.CurrentDirectory; 26 | 27 | var machine = Environment.MachineName; 28 | var software = request.ServerVariables["SERVER_SOFTWARE"]; 29 | 30 | return new ServerModel { Host = host, Root = root, Machine = machine, Software = software }; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/RollbarSharp/Builders/TraceChainModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using RollbarSharp.Serialization; 4 | 5 | namespace RollbarSharp.Builders 6 | { 7 | public static class TraceChainModelBuilder 8 | { 9 | /// 10 | /// Converts an ands his InnerExceptions to 11 | /// 's. 12 | /// 13 | /// 14 | /// 15 | public static IEnumerable CreateFromException(Exception exception) 16 | { 17 | var traces = new List(); 18 | var innerEx = exception; 19 | 20 | while (innerEx != null) 21 | { 22 | var exceptionModel = ExceptionModelBuilder.CreateFromException(innerEx); 23 | var frames = FrameModelBuilder.CreateFramesFromException(innerEx); 24 | 25 | traces.Insert(0, new TraceModel(exceptionModel, frames)); 26 | 27 | innerEx = innerEx.InnerException; 28 | } 29 | 30 | return traces; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Configuration.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | using Newtonsoft.Json; 3 | 4 | namespace RollbarSharp 5 | { 6 | public class Configuration 7 | { 8 | /// 9 | /// Default application code version 10 | /// 11 | public static string DefaultCodeVersion = null; 12 | 13 | /// 14 | /// Default endpoint URL for posting notices (default: https://api.rollbar.com/api/1/item/) 15 | /// 16 | public static string DefaultEndpoint = "https://api.rollbar.com/api/1/item/"; 17 | 18 | /// 19 | /// Default environment name used in notices. (default: production) 20 | /// 21 | public static string DefaultEnvironment = "production"; 22 | 23 | /// 24 | /// Default language name used in notices. (default: csharp) 25 | /// 26 | public static string DefaultLanguage = "csharp"; 27 | 28 | /// 29 | /// Default parameters that should be scrubbed from requests 30 | /// 31 | public static string[] DefaultScrubParams = 32 | new[] 33 | { 34 | "password", "password_confirmation", "confirm_password", 35 | "secret", "secret_token", 36 | "creditcard", "credit_card", "credit_card_number", "card_number", "ccnum", "cc_number" 37 | }; 38 | 39 | /// 40 | /// Encoding to use when communicating with the Rollbar endpoint (default: utf-8) 41 | /// 42 | public static string Encoding = "utf-8"; 43 | 44 | 45 | /// 46 | /// URL for the Rollbar API 47 | /// Setting: Rollbar.Endpoint 48 | /// 49 | public string Endpoint { get; set; } 50 | 51 | /// 52 | /// The server-side access token for your application in Rollbar. 53 | /// Also known as the post_server_item key 54 | /// 55 | /// Setting: Rollbar.AccessToken 56 | /// Default: None. You have to set this. 57 | /// 58 | public string AccessToken { get; set; } 59 | 60 | /// 61 | /// Version of the application that is running (see https://rollbar.com/blog/post/2013/09/17/resolving-rollbar-items-in-versions) 62 | /// 63 | /// Setting: Rollbar.CodeVersion 64 | /// Default: 65 | /// 66 | public string CodeVersion; 67 | 68 | /// 69 | /// Name of the environment this app is running in. Usually "production" or "staging" 70 | /// 71 | /// Setting: Rollbar.Environment 72 | /// Default: production 73 | /// 74 | public string Environment { get; set; } 75 | 76 | /// 77 | /// Platform running the code. E.g. Windows or IIS. 78 | /// 79 | /// Setting: Rollbar.Platform 80 | /// Default: 81 | /// 82 | public string Platform { get; set; } 83 | 84 | /// 85 | /// Code language. Defaults to csharp. 86 | /// 87 | /// Setting: Rollbar.Language 88 | /// Default: csharp 89 | /// 90 | public string Language { get; set; } 91 | 92 | /// 93 | /// .NET Framework version 94 | /// 95 | /// Setting: Rollbar.Framework 96 | /// Default: ".NET" + 97 | /// 98 | public string Framework { get; set; } 99 | 100 | /// 101 | /// GIT SHA hash of the running code 102 | /// 103 | /// Setting: Rollbar.GitSha 104 | /// Default: None. You have to set this. 105 | /// 106 | public string GitSha { get; set; } 107 | 108 | /// 109 | /// Parameters that should be scrubbed (replaced with asterisks) rather than 110 | /// being sent to rollbar. Such as passwords, secret keys, etc. 111 | /// 112 | public string[] ScrubParams { get; set; } 113 | 114 | /// 115 | /// Settings used to serialize the payload to JSON when posting to Rollbar 116 | /// 117 | public JsonSerializerSettings JsonSettings 118 | { 119 | get 120 | { 121 | return new JsonSerializerSettings 122 | { 123 | Formatting = Formatting.Indented, 124 | NullValueHandling = NullValueHandling.Ignore 125 | }; 126 | } 127 | } 128 | 129 | public Configuration(string accessToken) 130 | { 131 | Endpoint = DefaultEndpoint; 132 | AccessToken = accessToken; 133 | CodeVersion = DefaultCodeVersion; 134 | Environment = DefaultEnvironment; 135 | Platform = System.Environment.OSVersion.ToString(); 136 | Framework = ".NET " + System.Environment.Version; 137 | Language = DefaultLanguage; 138 | ScrubParams = DefaultScrubParams; 139 | } 140 | 141 | /// 142 | /// Creates a , reading values from App/Web.config 143 | /// Rollbar.AccessToken 144 | /// Rollbar.CodeVersion 145 | /// Rollbar.Endpoint 146 | /// Rollbar.Environment 147 | /// Rollbar.Platform 148 | /// Rollbar.CodeLanguage 149 | /// Rollbar.Framework 150 | /// Rollbar.GitSha 151 | /// 152 | /// 153 | public static Configuration CreateFromAppConfig() 154 | { 155 | var token = GetSetting("Rollbar.AccessToken"); 156 | 157 | if (string.IsNullOrEmpty(token)) 158 | throw new ConfigurationErrorsException("Missing access token at Rollbar.AccessToken"); 159 | 160 | var conf = new Configuration(token); 161 | 162 | conf.CodeVersion = GetSetting("Rollbar.CodeVersion") ?? conf.CodeVersion; 163 | conf.Endpoint = GetSetting("Rollbar.Endpoint") ?? conf.Endpoint; 164 | conf.Environment = GetSetting("Rollbar.Environment") ?? conf.Environment; 165 | conf.Platform = GetSetting("Rollbar.Platform") ?? conf.Platform; 166 | conf.Language = GetSetting("Rollbar.CodeLanguage") ?? conf.Language; 167 | conf.Framework = GetSetting("Rolllbar.Framework") ?? conf.Framework; 168 | conf.GitSha = GetSetting("Rollbar.GitSha"); 169 | 170 | var scrubParams = GetSetting("Rollbar.ScrubParams"); 171 | conf.ScrubParams = scrubParams == null ? DefaultScrubParams : scrubParams.Split(','); 172 | 173 | return conf; 174 | } 175 | 176 | protected static string GetSetting(string name, string fallback = null) 177 | { 178 | var setting = ConfigurationManager.AppSettings[name]; 179 | return string.IsNullOrEmpty(setting) ? fallback : setting; 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/RollbarSharp/IRollbarClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using RollbarSharp.Builders; 5 | using RollbarSharp.Serialization; 6 | 7 | namespace RollbarSharp 8 | { 9 | public interface IRollbarClient 10 | { 11 | Configuration Configuration { get; } 12 | 13 | /// 14 | /// Builds Rollbar requests from s or text messages 15 | /// 16 | /// This only builds the body of the request, not the whole notice payload 17 | DataModelBuilder NoticeBuilder { get; } 18 | 19 | /// 20 | /// Fires just before sending the final JSON payload to Rollbar 21 | /// 22 | event RollbarClient.RequestSendingEventHandler RequestStarting; 23 | 24 | /// 25 | /// Fires when we've received a response from Rollbar 26 | /// 27 | event RollbarClient.RequestCompletedEventHandler RequestCompleted; 28 | 29 | /// 30 | /// Sends an exception using the "critical" level 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | Task SendCriticalException(Exception ex, string title = null, Action modelAction = null, object userParam = null); 37 | 38 | /// 39 | /// Sends an exception using the "error" level 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// 45 | Task SendErrorException(Exception ex, string title = null, Action modelAction = null, object userParam = null); 46 | 47 | /// 48 | /// Sents an exception using the "warning" level 49 | /// 50 | /// 51 | /// 52 | /// 53 | /// 54 | Task SendWarningException(Exception ex, string title = null, Action modelAction = null, object userParam = null); 55 | 56 | /// 57 | /// Sends the given to Rollbar including 58 | /// the stack trace. 59 | /// 60 | /// 61 | /// 62 | /// Default is "error". "critical" and "warning" may also make sense to use. 63 | /// 64 | /// 65 | Task SendException(Exception ex, string title = null, string level = "error", Action modelAction = null, object userParam = null); 66 | 67 | /// 68 | /// Sends a text notice using the "critical" level 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// 74 | Task SendCriticalMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null); 75 | 76 | /// 77 | /// Sents a text notice using the "error" level 78 | /// 79 | /// 80 | /// 81 | /// 82 | /// 83 | Task SendErrorMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null); 84 | 85 | /// 86 | /// Sends a text notice using the "warning" level 87 | /// 88 | /// 89 | /// 90 | /// 91 | /// 92 | Task SendWarningMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null); 93 | 94 | /// 95 | /// Sends a text notice using the "info" level 96 | /// 97 | /// 98 | /// 99 | /// 100 | /// 101 | Task SendInfoMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null); 102 | 103 | /// 104 | /// Sends a text notice using the "debug" level 105 | /// 106 | /// 107 | /// 108 | /// 109 | /// 110 | Task SendDebugMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null); 111 | 112 | /// 113 | /// Sents a text notice using the given level of severity 114 | /// 115 | /// 116 | /// 117 | /// 118 | /// 119 | /// 120 | Task SendMessage(string message, string level, IDictionary customData = null, Action modelAction = null, object userParam = null); 121 | 122 | Task Send(DataModel data, object userParam); 123 | 124 | /// 125 | /// Serialize the given object for transmission 126 | /// 127 | /// 128 | /// 129 | string Serialize(object data); 130 | } 131 | } -------------------------------------------------------------------------------- /src/RollbarSharp/InternalExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.SessionState; 7 | 8 | namespace RollbarSharp 9 | { 10 | internal static class InternalExtensions 11 | { 12 | /// 13 | /// Convert a to a dictionary which is far more usable. 14 | /// 15 | /// 16 | /// 17 | public static IDictionary ToDictionary(this NameValueCollection col) 18 | { 19 | if (col == null || col.Count == 0) 20 | return new Dictionary(); 21 | 22 | return col.AllKeys.Where(key => key != null).ToDictionary(key => key, key => col[key]); 23 | } 24 | 25 | /// 26 | /// Convert the objects in a session dictionary to a readable string dictionary 27 | /// 28 | /// 29 | /// 30 | public static IDictionary ToDictionary(this HttpSessionState session) 31 | { 32 | if (session == null || session.Count == 0) 33 | return new Dictionary(); 34 | 35 | return session.Keys.Cast() 36 | .Where(key => key != null) 37 | .ToDictionary(key => key, key => session[key].Describe()); 38 | } 39 | 40 | /// 41 | /// Create a dictionary describing the files posted. 42 | /// The key is the form field name, value the file name, mime type, and size in bytes. 43 | /// 44 | /// 45 | /// 46 | public static IDictionary Describe(this HttpFileCollection files) 47 | { 48 | return files.AllKeys.ToDictionary(k => k, k => files[k].Describe()); 49 | } 50 | 51 | /// 52 | /// For uploaded files, build a string containing the file name, mime type, and size 53 | /// 54 | /// 55 | /// 56 | public static string Describe(this HttpPostedFile file) 57 | { 58 | if (file.ContentLength == 0 && string.IsNullOrEmpty(file.FileName)) 59 | return "[empty]"; 60 | 61 | return string.Format("{0} ({1}, {2} bytes)", file.FileName, file.ContentType, file.ContentLength); 62 | } 63 | 64 | /// 65 | /// Convert an unknown object into a readable string 66 | /// Strings and value types simply call the ToString() method 67 | /// Arrays are returned as a comma-separated list surrounded by square brackets 68 | /// Other objects return the type name, hash code, and their ToString() method 69 | /// 70 | /// 71 | /// 72 | public static string Describe(this object obj) 73 | { 74 | if (obj == null) 75 | return "(NULL)"; 76 | 77 | var type = obj.GetType(); 78 | 79 | if (type == typeof(string)) 80 | return obj.ToString(); 81 | 82 | if (type.IsValueType) 83 | return obj.ToString(); 84 | 85 | if (type.IsArray) 86 | { 87 | var temp = (Array)obj; 88 | return temp.Cast().Describe(); 89 | } 90 | 91 | return "<" + type.Name + ":0x" + obj.GetHashCode().ToString("X") + ">: " + obj; 92 | } 93 | 94 | public static string Describe(this IEnumerable source) 95 | { 96 | if (source == null) 97 | return "(null)"; 98 | 99 | return "[" + string.Join(", ", source.Select(x => x.Describe())) + "]"; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/RollbarSharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | [assembly: AssemblyTitle("RollbarSharp")] 4 | [assembly: AssemblyDescription("Bindings for the Rollbar (rollbar.com) error reporting system")] 5 | [assembly: AssemblyProduct("RollbarSharp")] 6 | [assembly: AssemblyVersion("0.3.5.0")] 7 | -------------------------------------------------------------------------------- /src/RollbarSharp/RequestCompletedEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace RollbarSharp 2 | { 3 | /// 4 | /// Event args fired when the response is received from the Rollbar endpoint 5 | /// 6 | public class RequestCompletedEventArgs 7 | { 8 | public Result Result { get; set; } 9 | 10 | public RequestCompletedEventArgs(Result result) 11 | { 12 | Result = result; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/RollbarSharp/RequestStartingEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace RollbarSharp 2 | { 3 | public class RequestStartingEventArgs 4 | { 5 | public string Payload { get; set; } 6 | public object UserParam { get; set; } 7 | 8 | public RequestStartingEventArgs(string payload, object userParam) 9 | { 10 | Payload = payload; 11 | UserParam = userParam; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Result.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Linq; 3 | 4 | namespace RollbarSharp 5 | { 6 | /// 7 | /// Result of a post to the Rollbar API. 8 | /// The API communicates general status using HTTP status codes which are mapped to status descriptions 9 | /// 10 | public class Result 11 | { 12 | /// 13 | /// HTTP status code from the Rollbar endpoint 14 | /// 15 | public int HttpStatusCode { get; set; } 16 | 17 | /// 18 | /// Raw response string. Usually JSON format. 19 | /// 20 | public string RawResponse { get; set; } 21 | 22 | /// 23 | /// Description of the status 24 | /// 25 | public string Message { get; protected set; } 26 | 27 | /// 28 | /// User-provided parameter from Send* functions 29 | /// 30 | public object UserParam { get; set; } 31 | 32 | /// 33 | /// Successful or not 34 | /// 35 | public bool IsSuccess { get { return HttpStatusCode == 200; } } 36 | 37 | public string Description 38 | { 39 | get 40 | { 41 | if (HttpStatusCode == 200) return "Success"; 42 | if (HttpStatusCode == 400) return "Bad or missing request data"; 43 | if (HttpStatusCode == 403) return "Access denied. Check your access token"; 44 | if (HttpStatusCode == 422) return "Unprocessable payload. Payload contains semantic errors."; 45 | if (HttpStatusCode == 429) return "Too many requests. Rate limit exceeded."; 46 | if (HttpStatusCode == 500) return "Internal server error."; 47 | return "Unknown"; 48 | } 49 | } 50 | 51 | public Result(int httpStatusCode, string rawResponse, object userParam) 52 | { 53 | HttpStatusCode = httpStatusCode; 54 | RawResponse = rawResponse; 55 | UserParam = userParam; 56 | TryParseResponse(rawResponse); 57 | } 58 | 59 | /// 60 | /// Responses are usually (always?) in JSON format 61 | /// 62 | /// 63 | protected void TryParseResponse(string response) 64 | { 65 | if (string.IsNullOrEmpty(response)) 66 | return; 67 | 68 | try 69 | { 70 | var hash = JsonConvert.DeserializeObject(response); 71 | Message = hash["message"].Value(); 72 | } 73 | catch 74 | { 75 | } 76 | } 77 | 78 | /// 79 | /// HTTP Status code + status description + message if not successful 80 | /// 81 | /// 82 | public override string ToString() 83 | { 84 | var desc = HttpStatusCode + ": " + Description; 85 | 86 | if (!IsSuccess) 87 | desc += ": " + (Message ?? RawResponse); 88 | 89 | return desc; 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/RollbarSharp/RollbarClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using RollbarSharp.Builders; 9 | using RollbarSharp.Serialization; 10 | 11 | namespace RollbarSharp 12 | { 13 | /// 14 | /// The Rollbar client. This is where applications will interact 15 | /// with Rollbar. There shouldn't be any need for them to deal 16 | /// with any objects aside from this 17 | /// 18 | public class RollbarClient : IRollbarClient 19 | { 20 | /// 21 | /// Signature for the handler fired when the request is complete 22 | /// 23 | /// 24 | /// 25 | public delegate void RequestCompletedEventHandler(object source, RequestCompletedEventArgs args); 26 | 27 | public delegate void RequestSendingEventHandler(object source, RequestStartingEventArgs args); 28 | 29 | public Configuration Configuration { get; protected set; } 30 | 31 | /// 32 | /// Builds Rollbar requests from s or text messages 33 | /// 34 | /// This only builds the body of the request, not the whole notice payload 35 | public DataModelBuilder NoticeBuilder { get; protected set; } 36 | 37 | /// 38 | /// Fires just before sending the final JSON payload to Rollbar 39 | /// 40 | public event RequestSendingEventHandler RequestStarting; 41 | 42 | /// 43 | /// Fires when we've received a response from Rollbar 44 | /// 45 | public event RequestCompletedEventHandler RequestCompleted; 46 | 47 | public RollbarClient(Configuration configuration) 48 | { 49 | Configuration = configuration; 50 | NoticeBuilder = new DataModelBuilder(Configuration); 51 | } 52 | 53 | /// 54 | /// Creates a new RollbarClient using the given access token 55 | /// and all default values 56 | /// 57 | /// 58 | public RollbarClient(string accessToken) 59 | : this(new Configuration(accessToken)) 60 | { 61 | } 62 | 63 | /// 64 | /// Creates a new RollbarClient using configuration values from app/web.config 65 | /// 66 | public RollbarClient() 67 | : this(Configuration.CreateFromAppConfig()) 68 | { 69 | } 70 | 71 | /// 72 | /// Sends an exception using the "critical" level 73 | /// 74 | /// 75 | /// 76 | /// 77 | /// 78 | public Task SendCriticalException(Exception ex, string title = null, Action modelAction = null, object userParam = null) 79 | { 80 | return SendException(ex, title, "critical", modelAction); 81 | } 82 | 83 | /// 84 | /// Sends an exception using the "error" level 85 | /// 86 | /// 87 | /// 88 | /// 89 | /// 90 | public Task SendErrorException(Exception ex, string title = null, Action modelAction = null, object userParam = null) 91 | { 92 | return SendException(ex, title, "error", modelAction); 93 | } 94 | 95 | /// 96 | /// Sents an exception using the "warning" level 97 | /// 98 | /// 99 | /// 100 | /// 101 | /// 102 | public Task SendWarningException(Exception ex, string title = null, Action modelAction = null, object userParam = null) 103 | { 104 | return SendException(ex, title, "warning", modelAction); 105 | } 106 | 107 | /// 108 | /// Sends the given to Rollbar including 109 | /// the stack trace. 110 | /// 111 | /// 112 | /// 113 | /// Default is "error". "critical" and "warning" may also make sense to use. 114 | /// 115 | /// 116 | public Task SendException(Exception ex, string title = null, string level = "error", Action modelAction = null, object userParam = null) 117 | { 118 | var notice = NoticeBuilder.CreateExceptionNotice(ex, title, level); 119 | if (modelAction != null) 120 | { 121 | modelAction(notice); 122 | } 123 | return Send(notice, userParam); 124 | } 125 | 126 | /// 127 | /// Sends a text notice using the "critical" level 128 | /// 129 | /// 130 | /// 131 | /// 132 | /// 133 | public Task SendCriticalMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null) 134 | { 135 | return SendMessage(message, "critical", customData, modelAction, userParam); 136 | } 137 | 138 | /// 139 | /// Sents a text notice using the "error" level 140 | /// 141 | /// 142 | /// 143 | /// 144 | /// 145 | public Task SendErrorMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null) 146 | { 147 | return SendMessage(message, "error", customData, modelAction, userParam); 148 | } 149 | 150 | /// 151 | /// Sends a text notice using the "warning" level 152 | /// 153 | /// 154 | /// 155 | /// 156 | /// 157 | public Task SendWarningMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null) 158 | { 159 | return SendMessage(message, "warning", customData, modelAction, userParam); 160 | } 161 | 162 | /// 163 | /// Sends a text notice using the "info" level 164 | /// 165 | /// 166 | /// 167 | /// 168 | /// 169 | public Task SendInfoMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null) 170 | { 171 | return SendMessage(message, "info", customData, modelAction, userParam); 172 | } 173 | 174 | /// 175 | /// Sends a text notice using the "debug" level 176 | /// 177 | /// 178 | /// 179 | /// 180 | /// 181 | public Task SendDebugMessage(string message, IDictionary customData = null, Action modelAction = null, object userParam = null) 182 | { 183 | return SendMessage(message, "debug", customData, modelAction); 184 | } 185 | 186 | /// 187 | /// Sents a text notice using the given level of severity 188 | /// 189 | /// 190 | /// 191 | /// 192 | /// 193 | /// 194 | public Task SendMessage(string message, string level, IDictionary customData = null, Action modelAction = null, object userParam = null) 195 | { 196 | var notice = NoticeBuilder.CreateMessageNotice(message, level, customData); 197 | if (modelAction != null) 198 | { 199 | modelAction(notice); 200 | } 201 | return Send(notice, userParam); 202 | } 203 | 204 | public Task Send(DataModel data, object userParam) 205 | { 206 | var payload = new PayloadModel(Configuration.AccessToken, data); 207 | return HttpPost(payload, userParam); 208 | } 209 | 210 | /// 211 | /// Serialize the given object for transmission 212 | /// 213 | /// 214 | /// 215 | public string Serialize(object data) 216 | { 217 | return JsonConvert.SerializeObject(data, Configuration.JsonSettings); 218 | } 219 | 220 | protected Task HttpPost(PayloadModel payload, object userParam) 221 | { 222 | var payloadString = Serialize(payload); 223 | return HttpPost(payloadString, userParam); 224 | } 225 | 226 | protected Task HttpPost(string payload, object userParam) 227 | { 228 | return Task.Factory.StartNew(() => HttpPostAsync(payload, userParam)); 229 | } 230 | 231 | protected void HttpPostAsync(string payload, object userParam) 232 | { 233 | // convert the json payload to bytes for transmission 234 | var payloadBytes = Encoding.GetEncoding(Configuration.Encoding).GetBytes(payload); 235 | 236 | var request = (HttpWebRequest) WebRequest.Create(Configuration.Endpoint); 237 | request.ContentType = "application/json"; 238 | request.Method = "POST"; 239 | request.ContentLength = payloadBytes.Length; 240 | 241 | OnRequestStarting(payload, userParam); 242 | 243 | // we need to wrap GetRequestStream() in a try block 244 | // if the endpoint is unreachable, that exception gets thrown here 245 | try 246 | { 247 | using (var stream = request.GetRequestStream()) 248 | { 249 | stream.Write(payloadBytes, 0, payloadBytes.Length); 250 | stream.Close(); 251 | } 252 | } 253 | catch (Exception ex) 254 | { 255 | OnRequestCompleted(new Result(0, ex.Message, userParam)); 256 | return; 257 | } 258 | 259 | // attempt to parse the response. wrap GetResponse() in a try block 260 | // since WebRequest throws exceptions for HTTP error status codes 261 | WebResponse response; 262 | 263 | try 264 | { 265 | response = request.GetResponse(); 266 | } 267 | catch (WebException ex) 268 | { 269 | if (ex.Response == null) 270 | { 271 | var failMsg = string.Format("Request failed. Status: {0}. Message: {1}", 272 | ex.Status, ex.Message); 273 | OnRequestCompleted(new Result(0, failMsg, userParam)); 274 | } 275 | else 276 | { 277 | OnRequestCompleted(ex.Response, userParam); 278 | } 279 | 280 | return; 281 | } 282 | catch (Exception ex) 283 | { 284 | OnRequestCompleted(new Result(0, ex.Message, userParam)); 285 | return; 286 | } 287 | 288 | OnRequestCompleted(response, userParam); 289 | } 290 | 291 | protected void OnRequestStarting(string payload, object userParam) 292 | { 293 | if (RequestStarting == null) 294 | return; 295 | 296 | RequestStarting(this, new RequestStartingEventArgs(payload, userParam)); 297 | } 298 | 299 | protected void OnRequestCompleted(WebResponse response, object userParam) 300 | { 301 | var responseCode = (int) ((HttpWebResponse) response).StatusCode; 302 | string responseText; 303 | 304 | using (var stream = response.GetResponseStream()) 305 | { 306 | if (stream == null) 307 | responseText = string.Empty; 308 | else 309 | { 310 | using (var reader = new StreamReader(stream)) 311 | { 312 | responseText = reader.ReadToEnd(); 313 | } 314 | } 315 | } 316 | 317 | var result = new Result(responseCode, responseText, userParam); 318 | OnRequestCompleted(result); 319 | } 320 | 321 | protected void OnRequestCompleted(Result result) 322 | { 323 | if (RequestCompleted == null) 324 | return; 325 | 326 | var args = new RequestCompletedEventArgs(result); 327 | RequestCompleted(this, args); 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /src/RollbarSharp/RollbarHttpModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | 4 | namespace RollbarSharp 5 | { 6 | public class RollbarHttpModule : IHttpModule 7 | { 8 | public void Init(HttpApplication context) 9 | { 10 | context.Error += SendError; 11 | } 12 | 13 | public void Dispose() 14 | { 15 | } 16 | 17 | private static void SendError(object sender, EventArgs e) 18 | { 19 | var application = (HttpApplication) sender; 20 | var ex = application.Server.GetLastError(); 21 | 22 | if (ex is HttpUnhandledException) 23 | ex = ex.InnerException; 24 | 25 | new RollbarClient().SendException(ex); 26 | } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /src/RollbarSharp/RollbarSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {43A8B009-CA64-4D25-845A-FE2A53890FBC} 8 | Library 9 | Properties 10 | RollbarSharp 11 | RollbarSharp 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | ..\..\packages\Newtonsoft.Json.5.0.1\lib\net45\Newtonsoft.Json.dll 38 | True 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /src/RollbarSharp/RollbarSharp.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $title$ 7 | Michael Roach,Patrick Wyatt,Alberto Monteiro,richardversluis 8 | Michael Roach 9 | https://github.com/mroach/RollbarSharp/blob/master/LICENSE.txt 10 | https://github.com/mroach/rollbarsharp 11 | false 12 | $description$ 13 | https://github.com/mroach/RollbarSharp/releases/tag/$version$ 14 | en-US 15 | rollbar 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/RollbarSharp/RollbarSharp.v2.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | 1000 3 | false 4 | false 5 | false 6 | true 7 | false 8 | false 9 | false 10 | false 11 | false 12 | true 13 | true 14 | false 15 | true 16 | true 17 | true 18 | 60000 19 | 20 | 21 | 22 | AutoDetect 23 | STA 24 | x86 25 | -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/BodyModel.cs: -------------------------------------------------------------------------------- 1 | namespace RollbarSharp.Serialization 2 | { 3 | /// 4 | /// There are two kinds of bodies: exceptions and messages 5 | /// 6 | public abstract class BodyModel 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/DataModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace RollbarSharp.Serialization 5 | { 6 | [JsonObject(MemberSerialization.OptIn)] 7 | public class DataModel 8 | { 9 | /// 10 | /// Application code version: https://rollbar.com/blog/post/2013/09/17/resolving-rollbar-items-in-versions 11 | /// 12 | [JsonProperty("code_version")] 13 | public string CodeVersion { get; set; } 14 | 15 | /// 16 | /// Running environment. E.g. production, staging, development 17 | /// 18 | [JsonProperty("environment")] 19 | public string Environment { get; set; } 20 | 21 | [JsonProperty("body")] 22 | public BodyModel Body { get; set; } 23 | 24 | /// 25 | /// UNIX timestamp of the error event 26 | /// 27 | [JsonProperty("timestamp")] 28 | public ulong Timestamp { get; set; } 29 | 30 | /// 31 | /// Severity. One of: critical, error, warning, info, debug 32 | /// 33 | [JsonProperty("level")] 34 | public string Level { get; set; } 35 | 36 | /// 37 | /// Code platform. E.g. browser, flash, heroku, google-app-engine 38 | /// 39 | [JsonProperty("platform")] 40 | public string Platform { get; set; } 41 | 42 | /// 43 | /// Code language. Will be defaulted to "csharp" 44 | /// 45 | [JsonProperty("language")] 46 | public string Language { get; set; } 47 | 48 | /// 49 | /// Name of the code's framework. Will be defaulted to ".net" 50 | /// 51 | [JsonProperty("framework")] 52 | public string Framework { get; set; } 53 | 54 | [JsonProperty("request")] 55 | public RequestModel Request { get; set; } 56 | 57 | [JsonProperty("person")] 58 | public PersonModel Person { get; set; } 59 | 60 | [JsonProperty("server")] 61 | public ServerModel Server { get; set; } 62 | 63 | /// 64 | /// Arbitrary JSON object describing the client environment. 65 | /// 66 | [JsonProperty("client")] 67 | public object Client { get; set; } 68 | 69 | /// 70 | /// An object containing arbitrary custom data 71 | /// 72 | [JsonProperty("custom")] 73 | public IDictionary Custom { get; set; } 74 | 75 | /// 76 | /// Optional identifier for which part of your application this event came from. 77 | /// Items can be searched by context (prefix search) 78 | /// For example, in an MVC app, this could be "controller#action". 79 | /// In a single-page javascript app, it could be the name of the current screen or route. 80 | /// 81 | [JsonProperty("context")] 82 | public string Context { get; set; } 83 | 84 | [JsonProperty("notifier")] 85 | public NotifierModel Notifier { get; set; } 86 | 87 | /// 88 | /// A string up to 40 characters long that identifies the "fingerprint" of this item. 89 | /// Items with the same fingerprint are grouped together in Rollbar. 90 | /// Rollbar will automatically compute a fingerprint, but you can pass one explicitly if you want to override it. 91 | /// 92 | [JsonProperty("fingerprint")] 93 | public string Fingerprint { get; set; } 94 | 95 | /// 96 | /// A string up to 255 characters that will be used as the item title in the Rollbar UI. 97 | /// Rollbar will automatically compute a title, but you can pass one explicitly if you want to override it. 98 | /// 99 | [JsonProperty("title")] 100 | public string Title { get; set; } 101 | 102 | public DataModel(string level, BodyModel body) 103 | { 104 | Level = level; 105 | Body = body; 106 | Custom = new Dictionary(); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/ExceptionBodyModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace RollbarSharp.Serialization 5 | { 6 | /// 7 | /// Model used when reporting an exception rather than a message 8 | /// 9 | [JsonObject(MemberSerialization.OptIn)] 10 | public class ExceptionBodyModel : BodyModel 11 | { 12 | /// 13 | /// Exception trace. Includes exception class, message, and backtrace. 14 | /// 15 | [JsonProperty("trace_chain")] 16 | public IEnumerable TraceChain { get; set; } 17 | 18 | public ExceptionBodyModel(IEnumerable traceChain) 19 | { 20 | TraceChain = traceChain; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/ExceptionModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace RollbarSharp.Serialization 6 | { 7 | /// 8 | /// Represents the details of the exception, but not the backtrace. 9 | /// 10 | [JsonObject(MemberSerialization.OptIn)] 11 | public class ExceptionModel 12 | { 13 | /// 14 | /// The class name of the exception (or some other string describing the error class) 15 | /// 16 | /// ArgumentException 17 | [JsonProperty("class")] 18 | public string Class { get; set; } 19 | 20 | /// 21 | /// The exception message (should not be prefixed with the class name) 22 | /// 23 | [JsonProperty("message")] 24 | public string Message { get; set; } 25 | 26 | /// 27 | /// Copy of the dictionary from the original 28 | /// that was thrown. 29 | /// 30 | public IDictionary Data { get; set; } 31 | 32 | public ExceptionModel(string exceptionClass, string message) 33 | { 34 | Class = exceptionClass; 35 | Message = message; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/FrameModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RollbarSharp.Serialization 4 | { 5 | /// 6 | /// Represents a frame of the backtrace. Some fields don't apply to 7 | /// .NET but we include them anyway for completeness. 8 | /// 9 | [JsonObject(MemberSerialization.OptIn)] 10 | public class FrameModel 11 | { 12 | /// 13 | /// Name of the file including path 14 | /// 15 | [JsonProperty("filename")] 16 | public string FileName { get; set; } 17 | 18 | /// 19 | /// Code line number. 20 | /// 21 | [JsonProperty("lineno")] 22 | public int LineNumber { get; set; } 23 | 24 | /// 25 | /// Name of the method 26 | /// 27 | [JsonProperty("method")] 28 | public string Method { get; set; } 29 | 30 | /// 31 | /// The line of code executing 32 | /// 33 | [JsonProperty("code")] 34 | public string Code { get; set; } 35 | 36 | /// 37 | /// An object containing pre and post code context, as lists of lines of code. 38 | /// Doesn't apply to .NET 39 | /// 40 | [JsonProperty("context")] 41 | public object Context { get; set; } 42 | 43 | public FrameModel(string fileName, int lineNumber = 0, string method = null) 44 | { 45 | FileName = fileName; 46 | LineNumber = lineNumber; 47 | Method = method; 48 | } 49 | 50 | /// 51 | /// Produce a formatted stack trace line similar to what you see in yellow screens of death 52 | /// 53 | /// 54 | public override string ToString() 55 | { 56 | var s = Code ?? Method; 57 | 58 | if (!string.IsNullOrEmpty(FileName)) 59 | s += " in " + FileName; 60 | 61 | if (LineNumber > 0) 62 | s += ":line " + LineNumber; 63 | 64 | return s; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/MessageBodyModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace RollbarSharp.Serialization 5 | { 6 | /// 7 | /// Model for a text only report. The message ends up as the 'body' key 8 | /// in the message model and all custom data fields are merged in. 9 | /// 10 | /// 11 | /// { 12 | /// message: { 13 | /// body: "my message text, 14 | /// custom_field: "my custom data" 15 | /// } 16 | /// } 17 | /// 18 | [JsonObject(MemberSerialization.OptIn)] 19 | public class MessageBodyModel : BodyModel 20 | { 21 | public string Message { get; set; } 22 | 23 | public IDictionary CustomData { get; set; } 24 | 25 | [JsonProperty("message")] 26 | internal IDictionary Serialized 27 | { 28 | get 29 | { 30 | var result = new Dictionary(CustomData); 31 | result["body"] = Message; 32 | return result; 33 | } 34 | } 35 | 36 | public MessageBodyModel(string message, IDictionary customData = null) 37 | { 38 | Message = message; 39 | CustomData = customData ?? new Dictionary(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/NotifierModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RollbarSharp.Serialization 4 | { 5 | /// 6 | /// Describes the notifier library/code that reported this item i.e. this .NET binding 7 | /// 8 | [JsonObject(MemberSerialization.OptIn)] 9 | public class NotifierModel 10 | { 11 | /// 12 | /// Name of the notifier. RollbarSharp in this case. 13 | /// 14 | [JsonProperty("name")] 15 | public string Name { get; set; } 16 | 17 | /// 18 | /// Version of the notifier. Defaults to the version from the assembly info 19 | /// 20 | [JsonProperty("version")] 21 | public string Version { get; set; } 22 | 23 | public NotifierModel() 24 | { 25 | } 26 | 27 | public NotifierModel(string name, string version) 28 | { 29 | Name = name; 30 | Version = version; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/PayloadModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RollbarSharp.Serialization 4 | { 5 | /// 6 | /// Wrapper for the whole payload. This is the access token as one item 7 | /// and the whole notice request as another 8 | /// 9 | [JsonObject(MemberSerialization.OptIn)] 10 | public class PayloadModel 11 | { 12 | /// 13 | /// Access token 14 | /// 15 | [JsonProperty("access_token")] 16 | public string AccessToken { get; set; } 17 | 18 | /// 19 | /// Body of the request 20 | /// 21 | [JsonProperty("data")] 22 | public DataModel Data { get; set; } 23 | 24 | public PayloadModel(string accessToken, DataModel data) 25 | { 26 | AccessToken = accessToken; 27 | Data = data; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/PersonModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RollbarSharp.Serialization 4 | { 5 | /// 6 | /// Object describing the user affected by the item. 'id' is required. 7 | /// 8 | [JsonObject(MemberSerialization.OptIn)] 9 | public class PersonModel 10 | { 11 | /// 12 | /// User ID of the affected user. A string up to 40 characters. Required. 13 | /// 14 | [JsonProperty("id")] 15 | public string Id { get; set; } 16 | 17 | /// 18 | /// Affected user's username. A string up to 255 characters. Optional. 19 | /// 20 | [JsonProperty("username")] 21 | public string Username { get; set; } 22 | 23 | /// 24 | /// Affected user's email address. A string up to 255 characters. Optional. 25 | /// 26 | [JsonProperty("email")] 27 | public string Email { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/RequestModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace RollbarSharp.Serialization 5 | { 6 | /// 7 | /// Describes the HTTP request that triggered the item being reported. 8 | /// 9 | /// The query_string and body parameters have been omitted since they seem redundant to GET and POST 10 | [JsonObject(MemberSerialization.OptIn)] 11 | public class RequestModel 12 | { 13 | /// 14 | /// The full request URL 15 | /// 16 | [JsonProperty("url")] 17 | public string Url { get; set; } 18 | 19 | /// 20 | /// The request method (e.g. "GET") 21 | /// 22 | [JsonProperty("method")] 23 | public string Method { get; set; } 24 | 25 | /// 26 | /// Request headers (cookies, user-agent, etc.) 27 | /// 28 | [JsonProperty("headers")] 29 | public IDictionary Headers { get; set; } 30 | 31 | /// 32 | /// Server-side session data stored in Session object 33 | /// 34 | [JsonProperty("session")] 35 | public IDictionary Session { get; set; } 36 | 37 | /// 38 | /// Any routing paramters (e.g. for use with ASP.NET MVC Routes) 39 | /// 40 | [JsonProperty("params")] 41 | public IDictionary Parameters { get; set; } 42 | 43 | /// 44 | /// List of GET parameters (query string params) 45 | /// 46 | [JsonProperty("GET")] 47 | public IDictionary QueryStringParameters { get; set; } 48 | 49 | /// 50 | /// List of POST parameters (form-posted data params) 51 | /// 52 | [JsonProperty("POST")] 53 | public IDictionary PostParameters { get; set; } 54 | 55 | /// 56 | /// The user's IP address as a string. 57 | /// 58 | [JsonProperty("user_ip")] 59 | public string UserIp { get; set; } 60 | 61 | /// 62 | /// Initialize a new and initialize Dictionary 63 | /// properties for easier access. 64 | /// 65 | public RequestModel() 66 | { 67 | Headers = new Dictionary(); 68 | Parameters = new Dictionary(); 69 | QueryStringParameters = new Dictionary(); 70 | PostParameters = new Dictionary(); 71 | 72 | // Ask Rollbar to capture the IP address of the application sending the report 73 | UserIp = "$remote_ip"; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/ServerModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RollbarSharp.Serialization 4 | { 5 | /// 6 | /// Describes the server and code environment. 7 | /// 8 | [JsonObject(MemberSerialization.OptIn)] 9 | public class ServerModel 10 | { 11 | /// 12 | /// The server hostname, e.g. "web1" or "web1.mysite.com" 13 | /// 14 | [JsonProperty("host")] 15 | public string Host { get; set; } 16 | 17 | /// 18 | /// Name of the computer running the code 19 | /// 20 | /// NOTE: This isn't an official property but it shows up 21 | [JsonProperty("machine")] 22 | public string Machine { get; set; } 23 | 24 | /// 25 | /// Server software running the code. e.g. IIS 26 | /// 27 | /// NOTE: This isn't an official property but it shows up 28 | [JsonProperty("software")] 29 | public string Software { get; set; } 30 | 31 | /// 32 | /// The path to the application code root, not including the final slash 33 | /// 34 | [JsonProperty("root")] 35 | public string Root { get; set; } 36 | 37 | /// 38 | /// The name of the checked out source control branch. Defaults to "master" 39 | /// 40 | [JsonProperty("branch")] 41 | public string Branch { get; set; } 42 | 43 | /// 44 | /// The name of the log file the item was found in 45 | /// 46 | [JsonProperty("log_file")] 47 | public string LogFile { get; set; } 48 | 49 | /// 50 | /// Git SHA of the running code revision. Use the full SHA. 51 | /// 52 | [JsonProperty("sha")] 53 | public string GitSha { get; set; } 54 | } 55 | } -------------------------------------------------------------------------------- /src/RollbarSharp/Serialization/TraceModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RollbarSharp.Serialization 4 | { 5 | /// 6 | /// Container for the exception detils as well as the backtrace frames 7 | /// 8 | [JsonObject(MemberSerialization.OptIn)] 9 | public class TraceModel 10 | { 11 | /// 12 | /// Description of the exception itself. Exception class and exception message. 13 | /// 14 | [JsonProperty("exception")] 15 | public ExceptionModel Exception { get; set; } 16 | 17 | /// 18 | /// Stack trace 19 | /// 20 | [JsonProperty("frames")] 21 | public FrameModel[] Frames { get; set; } 22 | 23 | public TraceModel(ExceptionModel ex, FrameModel[] frames) 24 | { 25 | Exception = ex; 26 | Frames = frames; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/RollbarSharp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------