GithubHelp home page GithubHelp logo

getsentry / sentry-dotnet-platform-abstractions Goto Github PK

View Code? Open in Web Editor NEW
11.0 9.0 8.0 82 KB

Abstractions to simplify retrieving platform information in .NET

License: MIT License

C# 88.24% PowerShell 8.05% Shell 3.71%
dotnet dotnet-core mono dotnet-framework system-information sdk-dotnet tag-archived

sentry-dotnet-platform-abstractions's Introduction

Discontinued.

The code was moved into the Sentry SDK for .NET. Targets below net461 were deleted in there.

This code base will not be updated.


Sentry.PlatformAbstractions

Travis AppVeyor

Package name NuGet
Sentry.PlatformAbstractions NuGet

The goal of this package is to simplify the .NET SDK by leaving the messy #ifdefs, platform specific code (operating system, runtime, etc) out into its own library. It also helps by allowing us to share code between the new .NET SDK and the current .NET SDK.

Most of the platform information used by the SDK goes to Sentry's Context Interface. When implementing this on SharpRaven it was clear that to get reliable information is not as trivial as it seems. This repo is an attempt to create a package which will provide reliable information in different types of apps.

Examples

For details, check the example project.

Runtime information

If you are interested in the runtime information, with .NET Standard 1.5 onwards you can use: RuntimeInformation.FrameworkDescription, which will give you a single string

For example, .NET Core 2.0.6 on Linux returns: .NET Core 4.6.0.0. Besides not telling you what was actually installed on the machine, to get the version number you would need to parse the string.

The following table compares the results of that API call to what this library returns:

Target OS RuntimeInformation.FrameworkDescription This library returns an object
.NET Framework 4.7.2 Windows .NET Framework 4.7.3101.0 Name: .NET Framework
Version: 4.7.2
.NET Core 1.1.7 macOS .NET Core 4.6.26201.01 Name: .NET Core
Version: 1.1.7
.NET Core 1.1.8 Linux .NET Core 4.6.26328.01 Name: .NET Core
Version: 1.1.8
.NET Core 2.0.6 macOS .NET Core 4.6.0.0 Name: .NET Core
Version: 2.0.6
.NET Core 2.0.6 Linux .NET Core 4.6.0.0 Name: .NET Core
Version: 2.0.6
Mono 5.10.1.47 macOS 5.10.1.47 (2017-12/8eb8f7d5e74
Fri Apr 13 20:18:12 EDT 2018)
Name: Mono
Version: Mono 5.10.1.47
Mono 5.12.0.226 Linux 5.12.0.226 (tarball Thu May 3 09:48:32 UTC 2018) Name: Mono
Version: 5.12.0.226

It also includes extension methods to Runtime:

  • IsMono()
  • IsNetCore()
  • IsNetFx()

Supported frameworks

This library supports:

  • .NET Framework 3.5 and later
  • .NET Standard 1.5 and later

Building

Install .NET Core

.NET Core 2.0.x and 1.1.x SDKs.

Windows

.NET Framework, 4.7.1 or later

.\build.ps1

Linux and macOS

Install Mono 5.12 or later

./build.sh

Resources

sentry-dotnet-platform-abstractions's People

Contributors

bruno-garcia avatar joaopgrassi avatar tonyo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sentry-dotnet-platform-abstractions's Issues

Get OS information

Define an API to get the OS name, version, kernel, etc.

Ideally the NETStandard targets would work on Xamarin.iOS, Xamarin.Android, Unity (including IL2CPP, although it might not be possible) as well as .NET Core, .NET Framework and Mono on Windows, Linux and macOS.

Windows 10

RuntimeInformation.OSDecription: On Windows 10 returns: 10.0.17134
Now when I read this Microsoft announcement they talk about "Windows 10, version 1803". This library shall report the latter version which is what is used to talk about Windows versions.

Differentiating between Windows Server and Desktop edition.

It'll need some IsServer field but, how is this going to work on Linux? What defines Linux desktop or server?

On macOS, iOS, iPad and Linux it returns: Unix. on Xamarin, Mono and for compatibility reasons, also on CoreCLR.

On Mono, to know whether you are on Unix or not, is straightforward. But finding out which distribution on Linux (something like this) and which macOS version, is not.

Differentiating between iPad, iOS and macOS?

Mono has some code that perhaps could be used when runtime is Mono.

Consider the approached used by Pkcs11Interop

Differentiating between different Linux distributions.

To consider:
Environment.OSVersion calls under the hood GetVersionEx, deprecated since Windows 8.1
That means that calling it from a .NET Core app 2.0 on a Windows 10 will return: 6.2.9200.0
That is the Windows 8 version! Super confusing stuff.

On .NET 4.0 target. There’s no RuntimeInformation.OSDescription so how to get the OS Version? Environment.OSVersion gives you potential wrong data. Take some examples from CoreCLR 2.0:

macOS:
Environment.OSVersion:                                  Unix 17.5.0.0
Environment.OSVersion.Platform:                         Unix
Environment.OSVersion.VersionString:                    Unix 17.5.0.0
Environment.OSVersion.Version.Build:                    0
Environment.OSVersion.Version:                          17.5.0.0
RuntimeInformation.OSDescription:                       Darwin 17.5.0 Darwin Kernel Version 17.5.0: Mon Mar  5 22:24:32 PST 2018; root:xnu-4570.51.1~1/RELEASE_X86_64

Kali WSL:
Environment.OSVersion:                                  Unix 4.4.0.43
Environment.OSVersion.Platform:                         Unix
Environment.OSVersion.VersionString:                    Unix 4.4.0.43
Environment.OSVersion.Version.Build:                    0
Environment.OSVersion.Version:                          4.4.0.43
RuntimeInformation.OSDescription:                       Linux 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014

CentOS
Environment.OSVersion:                                  Unix 3.10.0.693
Environment.OSVersion.Platform:                         Unix
Environment.OSVersion.VersionString:                    Unix 3.10.0.693
Environment.OSVersion.Version.Build:                    0
Environment.OSVersion.Version:                          3.10.0.693
RuntimeInformation.OSDescription:                       Linux 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018

Windows 10 Pro:
Environment.OSVersion:                                  Microsoft Windows NT 6.2.9200.0
Environment.OSVersion.Platform:                         Win32NT
Environment.OSVersion.VersionString:                    Microsoft Windows NT 6.2.9200.0
Environment.OSVersion.Version.Build:                    9200
Environment.OSVersion.Version:                          6.2.9200.0
RuntimeInformation.OSDescription:                       Microsoft Windows 10.0.16299         

Consider the current implementation on SharpRaven

Consistently expose all API's across all targets

The code that retrieves the .NET Framework installation (FrameworkInstallations) it's not available on netstandard.

This is an issue because netstandard libraries (that could run on Full Framework apps) that depend on Sentry.PlatformAbstractions will not be able to see it.

So, we need to expose all API in all targets. If the API is not available on the target, the implementation will be a no-op.

Report Runtime information in reliable way.

Through #237 we've added support to Contexts Interface.

The Runtime information extraction was best effort considering that not even Microsoft has figured out a way to do this properly.

For NET Standard 2.0 we used RuntimeInformation.FrameworkDescription:

On non NET Standard 2.0, it'll fallback to: Environment.Version
This is an issue with .NET Framework 4.6+ as it displays the same version for all newer versions (4.6.1, 4.6.2, 4.7, 4.7.1). Microsoft has a guide on finding out the right .NET Framework version installed and since all of these 4.x versions are all in-place installation on CLR 4, the latest version installed is the version we should report, not the version an assembly was targeting when compiled.

BenchmarkDotNet had good progress with this.

API to retrieve the entry assembly

The standard API to get it is:

Assembly.GetEntryAssembly()

The problem is it can return null.

We need a reliable way to get the top most entry assembly. In case it was unmanaged, then the first managed after that should work fine.

One of the approaches is to stack walk until locating the call from unmanaged code and take the assembly immediately before that. That was implemented on SharpRaven which could serve as a good starting point. It's based on an SO answer but added support to Mono too.

The goal here is to have a simple API that will make an extra effort to find the main application assembly.

Proposed API:

public class AssemblyInfo
{
    public static Assembly GetEntryAssembly();
}

API to retrieve CPU and App architecture

The goal is to have a simple API that will return:

  1. Operating system architecture
  2. Application architecture

SharpRaven has some implementation although it mixes things a bit:

One thing to keep in mind is the difference of OS arch and App arch. An app can be 32 bit on a 64 bit operating system.

.NET Standard 2.0 include API for both:

  1. RuntimeInformation.OSArchitecture
  2. RuntimeInformation.ProcessArchitecture

Both return a value from the enum:

  public enum Architecture
  {
    X86, X64, Arm, Arm64,
  }

That is good news. It is also supported by Xamarin/iOS/Mac/Android but we still need to find a way on other targets since this is not available on .NET Framework prior to 4.7.1 according to MSDN

To verify the CPU arch, the SharpRaven version linked above also considers environment variable, which should always be available on Windows but is not reliable on macOS nor Linux since it's non-POSIX, bash extension. The code also calls into Win32 API when verifying the OS version supports it. It does so without a IsWindows call before doing so. This should be considered on the new implementation.

To check the App arch, a reliable way is simply: IntPtr.Size == 8 means 64bit. Although not sure if it's ia32 or arm32 or what. With that it's also known that the OS arch is 64 bit which could be a quick path for OS arch API.
On Windows a platform call like this can be considered.

A possibility for macOS, with P/Invoke is get_arch_name_from_types

As any other API in this repo, would be great to get it tested with CoreRT or other AoT runtimes like Unity or what not.

Benchmarking different calls would be interesting although challenging since the benchmark will behave differently in different platforms.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.