Scott Hanselman

Peachpie - Open Source PHP Compiler to .NET and WordPress under ASP.NET Core

July 28, 2017 Comment on this post [13] Posted in DotNetCore | Open Source | PHP
Sponsored By

The Peachpie PHP compiler project joined the .NET Foundation this week and I'm trying to get my head around it. PHP in .NET? PHP on .NET? Under .NET? What compiles to what? Why would I want this? How does it work? Does it feel awesome or does it feel gross?

image

Just drink this in.

C:\Users\scott\Desktop\peachcon> type program.php
<?php

function main()
{
echo "Hello .NET World!";
}

main();

C:\Users\scott\Desktop\peachcon> dotnet run
Hello .NET World!

Just like that. Starting from a .NET SDK (They say 1.1, although I used a 2.0 preview) you just add their templates

dotnet new -i Peachpie.Templates::*

Then dotnet new now shows a bunch of php options.

C:\Users\scott\Desktop\peachcon> dotnet new | find /i "php"
Peachpie console application peachpie-console PHP Console
Peachpie Class library peachpie-classlibrary PHP Library
Peachpie web application peachpie-web PHP Web/Empty

dotnet new peachpie-console for example, then dotnet restore and dotnet run. Boom.

NOTE: I did have to comment out his one line "<Import Project="$(CSharpDesignTimeTargetsPath)" />" in their project file that doesn't work at the command line. It's some hack they did to make things work in Visual Studio but I'm using VS Code. I'm sure it's an alpha-point-in-time thing.

It's really compiling PHP into .NET Intermediate Language!

PHP to .NET

You can see my string here:

Hello .NET World inside a PHP app inside the CLR

But...why? Here's what they say, and much of it makes sense to me.

  1. Performance: compiled code is fast and also optimized by the .NET Just-in-Time Compiler for your actual system. Additionally, the .NET performance profiler may be used to resolve bottlenecks.
  2. C# Extensibility: plugin functionality can be implemented in a separate C# project and/or PHP plugins may use .NET libraries.
  3. Sourceless distribution: after the compilation, most of the source files are not needed.
  4. Power of .NET: Peachpie allows the compiled WordPress clone to run in a .NET JIT'ted, secure and manageable environment, updated through windows update.
  5. No need to install PHP: Peachpie is a modern compiler platform and runtime distributed as a dependency to your .NET project. It is downloaded automatically on demand as a NuGet package or it can be even deployed standalone together with the compiled application as its library dependency.

PHP does have other VMs/Runtimes that are used (beyond just PHP.exe) but the idea that I could reuse code between PHP and C# is attractive, not to mention the "PHP as dependency" part. Imagine if I have an existing .NET shop or project and now I want to integrate something like WordPress?

PHP under ASP.NET Core

Their Web Sample is even MORE interesting, as they've implemented PHP as ASP.NET Middleware. Check this out. See where they pass in the PHP app as an assembly they compiled?

using Peachpie.Web;

namespace peachweb.Server
{
class Program
{
static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://*:5004/")
.UseStartup<Startup>()
.Build();

host.Run();
}
}

class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache();

services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.CookieHttpOnly = true;
});
}

public void Configure(IApplicationBuilder app)
{
app.UseSession();

app.UsePhp(new PhpRequestOptions(scriptAssemblyName: "peachweb"));
app.UseDefaultFiles();
app.UseStaticFiles();
}
}
}

Interesting, but it's still Hello World. Let's run WordPress under PeachPie (and hence, under .NET). I'll run MySQL in a local Docker container for simplicity:

docker run -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -p 3306:3306 -d mysql

I downloaded WordPress from here (note they have the "app" bootstrapper" that hosts .NET and then runs WordPress) restore and run.

WordPress under .NET Core

It's early and it's alpha - so set your expectations appropriately - but it's surprisingly useful and appears to be under active development.

What do you think?

Be sure to explore their resources at http://www.peachpie.io/resources and watch their video of WordPress running on .NET. It's all Open Source, in the .NET Foundation, and the code is up at https://github.com/iolevel/ and you can get started here: http://www.peachpie.io/getstarted


Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

dotnet sdk list and dotnet sdk latest

July 27, 2017 Comment on this post [6] Posted in DotNetCore
Sponsored By

dotnet sdk listCan someone make .NET Core better with a simple global command? Fanie Reynders did and he did it in a simple and elegant way. I'm envious, in fact, because I spec'ed this exact thing out in a meeting a few months ago but I could have just done it like he did and I would have used fewer keystrokes!

Last year when .NET Core was just getting started, there was a "DNVM" helper command that you could use to simplify dealing with multiple versions of the .NET SDK on one machine. Later, rather than 'switching global SDK versions,' switching was simplified to be handled on a folder by folder basis. That meant that if you had a project in a folder with no global.json that pinned the SDK version, your project would use the latest installed version. If you liked, you could create a global.json file and pin your project's folder to a specific version. Great, but I would constantly have to google to remember the format for the global.json file, and I'd constantly go into c:\Program Files\dotnet in order to get a list of the currently installed SDKs. I proposed that Microsoft make a "dotnet sdk list" command and the ability to pin down versions like "dotnet sdk 1.0.4" and even maybe install new ones with "dotnet sdk install 2.1.0" or something.

Fanie did all this for us except the installation part, and his implementation is clean and simple. It's so simple that I just dropped his commands into my Dropbox's Utils folder that I have in my PATH on all my machines. Now every machine I dev on has this extension.

UPDATE: There is both a Windows version and a bash version here.

Note that if I type "dotnet foo" the dotnet.exe driver will look in the path for an executable command called dotnet-foo.* and run it.

C:\Users\scott\Desktop>dotnet foo
No executable found matching command "dotnet-foo"

C:\Users\scott\Desktop>dotnet sdk
No executable found matching command "dotnet-sdk"

He created a dotnet-sdk.cmd you can get on his GitHub. Download his repo and put his command somewhere in your path. Now I can do this:

C:\Users\scott\Desktop>dotnet sdk list
The installed .NET Core SDKs are:
1.0.0
1.0.0-preview2-003131
1.0.0-rc3-004530
1.0.2
1.0.4

Which is lovely, but the real use case is this:

C:\Users\scott\Desktop\fancypants>dotnet --version
1.0.4

C:\Users\scott\Desktop\fancypants>dotnet sdk 1.0.0
Switching .NET Core SDK version to 1.0.0

C:\Users\scott\Desktop\fancypants>dotnet --version
1.0.0

C:\Users\scott\Desktop\fancypants>dir
Volume in drive C is Windows
Directory of C:\Users\scott\Desktop\fancypants

07/26/2017 04:53 PM 47 global.json
1 File(s) 47 bytes

Then if I go "dotnet sdk latest" it just deletes the global.json. Perhaps in a perfect world it should just remove the sdk JSON node in case global.json has been modified, but for now it's great. Without the global.json the dotnet.exe will just use your latest installed SDK.

This works with .NET Core 2.0 as well. This should be built-in, but for now it's a very nice example of a clean extension to dotnet.exe.

Oh, and by the way, he also made a ".net.cmd" so you can do this with all your dotnet.exe commands.

.NET run

Give these commands a try!


Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Monospaced Programming Fonts with Ligatures

July 21, 2017 Comment on this post [54] Posted in Musings | Open Source
Sponsored By

Animation of how ligature fonts change as you typeTypographic ligatures are when multiple characters appear to combine into a single character. Simplistically, when you type two or more characters and they magically attach to each other, you're using ligatures that were supported by your OS, your app, and your font.

I did a blog post in 2011 on using OpenType Ligatures and Stylistic Sets to make nice looking wedding invitations. Most English laypeople aren't familiar with ligatures as such and are impressed by them! However, if your language uses ligatures as a fundamental building block, this kind of stuff is old hat. Ligatures are fundamental to Arabic script and when you're typing it up you'll see your characters/font change and ligatures be added as you type. For example here is ل ا with a space between them, but this is لا the same two characters with no space. Ligatures kicked in.

OK, let's talk programming. Picking a programming font is like picking a religion. No matter what you pick someone will say you're wrong. Most people will agree at least that monospaced fonts are ideal for reading code and that both of you who use proportionally spaced fonts are destined for hell, or at the very least, purgatory.

Beyond that, there's some really interesting programming fonts that have ligature support built in. It's important that you - as programmers - understand and remember that ligatures are just a view on the bytes that are your code. If you custom make a font that makes the = equals site a poop emoji, that's between you and your font. The same thing applies to ligatures. Your code is the same.

Three of the most interesting and thoughtful monospaced programming fonts with ligatures are Fira Code, Monoid, and Hasklig. I say "thoughtful" but that's what I really mean - these folks have designed these fonts with programming in mind, considering spacing, feel, density, pleasantness, glance-ability, and a dozen other things that I'm not clever enough to think of.

I'll be doing screenshots (and coding) in the free cross-platform Visual Studio Code. Go to your User Settings (Ctrl-,) or File | Preferences, and add your font name and turn on ligatures if you want to follow along. Example:

// Place your settings in this file to overwrite the default settings
{
    "editor.fontSize": 20,
    "editor.fontLigatures": true,
    "editor.fontFamily": "Fira Code"
}

Most of these fonts have dozens and dozens of ligature combinations and there is no agreement for "make this a single glyph" or "use ligatures for -> but not ==> so you'll need to try them out with YOUR code and make a decision for yourself. My sample code example can't be complete and how it looks and feels to you on your screen is all that matters.

Here's my little sample. Note the differences.

// FIRA CODE
object o;
if (o is int i || (o is string s &&
int.TryParse(s, out i)) { /* use i */ }
var x = 0xABCDEF;
-> --> ==> != === !== && ||<=<
</><tag> http://www.hanselman.com
<=><!-- HTML Comment -->
i++; #### ***

Fira Code

Fira Code

There's so much here. Look at how "www" turned into an interesting glyph. Things like != and ==> turn into arrows. HTML Comments are awesome. Double ampersands join together.

I was especially impressed by the redefined hex "x". See how it's higher up and smaller than var x?

Monoid

Monoid

Monoid prides itself on being crisp and readable on retina displays as well as at 9pt on low-res displays. I frankly can't understand how tiny font people can function. It gives me a headache to even consider programming at anything less than 14 to 16pt and I am usually around 20pt. And my vision is fine. ;)

image

Monoid's goal is to be sleek and precise and the designer has gone out of their way to make sure there's no confusion between any two characters.

Hasklig

Hasklig takes the Source Code Pro font and adds ligatures. As you can tell by the name, it's great in Haskell, as for a while a number of Haskell people were taking to using single character (tiny) Unicode glyphs like ⇒ for things like =>. Clearly this was a problem best solved by ligatures.

Hasklig

Do any of you use programming fonts with ligatures? I'm impressed with Fira Code, myself, and I'm giving it a try this month.


Sponsor: Thanks to Redgate! A third of teams don’t version control their database. Connect your database to your version control system with SQL Source Control and find out who made changes, what they did, and why. Learn more

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

13 hours debugging a segmentation fault in .NET Core on Raspberry Pi and the solution was...

July 18, 2017 Comment on this post [63] Posted in Bugs | DotNetCore
Sponsored By

Debugging is a satisfying and special kind of hell. You really have to live it to understand it. When you're deep into it you never know when it'll be done. When you do finally escape it's almost always a DOH! moment.

I spent an entire day debugging an issue and the solution ended up being a checkbox.

NOTE: If you get a third of the way through this blog post and already figured it out, well, poop on you. Where were you after lunch WHEN I NEEDED YOU?

I wanted to use a Raspberry Pi in a tech talk I'm doing tomorrow at a conference. I was going to show .NET Core 2.0 and ASP.NET running on a Raspberry Pi so I figured I'd start with Hello World. How hard could it be?

You'll write and build a .NET app on Windows or Mac, then publish it to the Raspberry Pi. I'm using a preview build of the .NET Core 2.0 command line and SDK (CLI) I got from here.

C:\raspberrypi> dotnet new console
C:\raspberrypi> dotnet run
Hello World!
C:\raspberrypi> dotnet publish -r linux-arm
Microsoft Build Engine version for .NET Core

raspberrypi1 -> C:\raspberrypi\bin\Debug\netcoreapp2.0\linux-arm\raspberrypi.dll
raspberrypi1 -> C:\raspberrypi\bin\Debug\netcoreapp2.0\linux-arm\publish\

Notice the simplified publish. You'll get a folder for linux-arm in this example, but could also publish osx-x64, etc. You'll want to take the files from the publish folder (not the folder above it) and move them to the Raspberry Pi. This is a self-contained application that targets ARM on Linux so after the prerequisites that's all you need.

I grabbed a mini-SD card, headed over to https://www.raspberrypi.org/downloads/ and downloaded the latest Raspbian image. I used etcher.io - a lovely image burner for Windows, Mac, or Linux - and wrote the image to the SD Card. I booted up and got ready to install some prereqs. I'm only 15 min in at this point. Setting up a Raspberry Pi 2 or Raspberry Pi 3 is VERY smooth these days.

Here's the prereqs for .NET Core 2 on Ubuntu or Debian/Raspbian. Install them from the terminal, natch.

sudo apt-get install libc6 libcurl3 libgcc1 libgssapi-krb5-2 libicu-dev liblttng-ust0 libssl-dev libstdc++6 libunwind8 libuuid1 zlib1g

I also added an FTP server and ran vncserver, so I'd have a few ways to talk to the Raspberry Pi. Yes, I could also SSH in but I have a spare monitor, and with that monitor plus VNC I didn't see a need.

sudo apt-get pure-ftpd
vncserver

Then I fire up Filezilla - my preferred FTP client - and FTP the publish output folder from my dotnet publish above. I put the files in a folder off my ~\Desktop.

FTPing files

Then from a terminal I

pi@raspberrypi:~/Desktop/helloworld $ chmod +x raspberrypi

(or whatever the name of your published "exe" is. It'll be the name of your source folder/project with no extension. As this is a self-contained published app, again, all the .NET Core runtime stuff is in the same folder with the app.

pi@raspberrypi:~/Desktop/helloworld $ ./raspberrypi 
Segmentation fault

The crash was instant...not a pause and a crash, but it showed up as soon as I pressed enter. Shoot.

I ran "strace ./raspberrypi" and got this output. I figured maybe I missed one of the prerequisite libraries, and I just needed to see which one and apt-get it. I can see the ld.so.nohwcap error, but that's a historical Debian-ism and more of a warning than a fatal.

strace on a bad exe in Linux

I used to be able to read straces 20 years ago but much like my Spanish, my skills are only good at Chipotle. I can see it just getting started loading libraries, seeking around in them, checking file status,  mapping files to memory, setting memory protection, then it all falls apart. Perhaps we tried to do something inappropriate with some memory that just got protected? We are dereferencing a null pointer.

Maybe you can read this and you already know what is going to happen! I did not.

I run it under gdb:

pi@raspberrypi:~/Desktop/WTFISTHISCRAP $ gdb ./raspberrypi 
GNU gdb (Raspbian 7.7.1+dfsg-5+rpi1) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
This GDB was configured as "arm-linux-gnueabihf".
"/home/pi/Desktop/helloworldWRONG/./raspberrypi1": not in executable format: File truncated
(gdb)

Ok, sick files?

I called Peter Marcu from the .NET team and we chatted about how he got it working and compared notes.

I was using a Raspberry Pi 2, he a Pi 3. Ok, I'll try a 3. 30 minutes later, new SD card, new burn, new boot, pre-reqs, build, FTP, run, SAME RESULT - segfault.

Weird.

Maybe corruption? Here's a thread about Corrupted Files on Raspbian Jesse 2017-07-05! That's the version I have. OK, I'll try the build of Raspbian from a week before.

30 minutes later, burn another SD card, new boot, pre-reqs, build, FTP, run, SAME RESULT - segfault.

BUT IT WORKS ON PETER'S MACHINE.

Weird.

Maybe a bad nuget.config? No.

Bad daily .NET build? No.

BUT IT WORKS ON PETER'S MACHINE.

Ok, I'll try Ubuntu Mate for Raspberry Pi. TOTALLY different OS.

30 minutes later, burn another SD card, new boot, pre-reqs, build, FTP, run, SAME RESULT - segfault.

What's the common thread here? Ok, I'll try from another Windows machine.

SAME RESULT - segfault.

I call Peter back and we figure it's gotta be prereqs...but the strace doesn't show we're even trying to load any interesting libraries. We fail FAST.

Ok, let's get serious.

We both have Raspberry Pi 3s. Check.

What kind of SD card does he have? Sandisk? Ok,  I'll use Sandisk. But disk corruption makes no sense at that level...because the OS booted!

What did he burn with? He used Win32diskimager and I used Etcher. Fine, I'll bite.

30 minutes later, burn another SD card, new boot, pre-reqs, build, FTP, run, SAME RESULT - segfault.

He sends me HIS build of a HelloWorld and I FTP it over to the Pi. SAME RESULT - segfault.

Peter is freaking out. I'm deeply unhappy and considering quitting my job. My kids are going to sleep because it's late.

I ask him what he's FTPing with, and he says WinSCP. I use FileZilla, ok, I'll try WinSCP.

WinSCP's New Session dialog starts here:

SFTP is Default

I say, WAIT. Are you using SFTP or FTP? Peter says he's using SFTP so I turn on SSH on the Raspberry Pi and SFTP into it with WinSCP and copy over my Hello World.

IT FREAKING WORKS. IMMEDIATELY.

Hello World on a Raspberry Pi

BUT WHY.

I make a folder called Good and a folder called BAD. I copy with FileZilla to BAD and with WinSCP to GOOD. Then I run a compare. Maybe some part of .NET Core got corrupted? Maybe a supporting native library?

pi@raspberrypi:~/Desktop $ diff --brief -r helloworld/ helloworldWRONG/
Files helloworld/raspberrypi1 and helloworldWRONG/raspberrypi1 differ

Wait, WHAT? The executable are different? One is 67,684 bytes and the bad one is 69,632 bytes.

Time for a  visual compare.

All the ODs are gone

At this point I saw it IMMEDIATELY.

0D is CR (13) and 0A is LF (10). I know this because I'm old and I've written printer drivers for printers that had both carriages and lines to feed. Why do YOU know this? Likely because you've transferred files between Unix and Windows once or thrice, perhaps with FTP or Git.

All the CRs are gone. From my binary file.

Why?

I went straight to settings in FileZilla:

Treat files without extensions as ASCII files

See it?

Treat files without extensions as ASCII files

That's the default in FileZilla. To change files that are just chilling, minding their own business, as ASCII, and then just randomly strip out carriage returns. What could go wrong? And it doesn't even look for CR LF pairs! No, it just looks for CRs and strips them. Classy.

In retrospect I should have used known this, but it wasn't even the switch to SFTP, it was the switch to an FTP program with different defaults.

This bug/issue whatever burned my whole Monday. But, it'll never burn another Monday, Dear Reader, because I've seen it before now.

FAIL FAST FAIL OFTEN my friends!

Why does experience matter? It means I've failed a lot in the past and it's super useful if I remember those bugs because then next time this happens it'll only burn a few minutes rather than a day.

Go forth and fail a lot, my loves.

Oh, and FTP sucks.


Sponsor: Thanks to Redgate! A third of teams don’t version control their database. Connect your database to your version control system with SQL Source Control and find out who made changes, what they did, and why. Learn more

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Ubuntu now in the Windows Store: Updates to Linux on Windows 10 and Important Tips

July 11, 2017 Comment on this post [15] Posted in Linux | Win10
Sponsored By

I noticed this blog post about Ubuntu over at the Microsoft Command Line blog. Ubuntu is now available from the Windows Store for builds of Windows over 16215.

image

You can run "Winver" to see your build number of Windows. If you run Windows 10 you can certainly sign up for the Windows Insiders builds, or you can wait a few months until these features make their way to the mainstream. I've been running Windows 10 Insiders "Fast ring" for a while with a few issues but nothing blocking.

The addition of Ubuntu to the Windows Store may initially seem confusing or even a little bizarre. However, given a minute to understand the larger architecture it make a lot of sense. However, for those of us who have been beta-testing these features, the move to the Windows Store will require some manual steps in order for you to reap the benefits.

Here's how I see it.

  • For the early betas of the Windows Subsystem for Linux you type bash from anywhere and it runs Ubuntu on Windows.
  • Ubuntu on Windows hides its filesystem in C:\Users\scott\AppData\Local\somethingetcetc and you shouldn't go there or touch it.
  • By moving the tar files and Linux distro installation into the store, that allows us users to use the Store's CDN (Content Distrubution Network) to get Distros quickly and easily. 
    • Just turn on the feature and REBOOT
      Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

then hit the store to get the binaries!

Ok, now this is where and why it gets interesting.

Soon (later this month I'm told) we will be able to have n number of native Linux distros on our Windows 10 machines at one time. You can install as many as you like from the store. No VMs, just fast Linux...on Windows!

There is a utility for the Windows Subsystem for Linux called "wslconfig" that Windows 10 has.

C:\>wslconfig
Performs administrative operations on Windows Subsystem for Linux

Usage:
/l, /list [/all] - Lists registered distributions.
/all - Optionally list all distributions, including distributions that
are currently being installed or uninstalled.
/s, /setdefault <DistributionName> - Sets the specified distribution as the default.
/u, /unregister <DistributionName> - Unregisters a distribution.

C:\WINDOWS\system32>wslconfig /l
Windows Subsystem for Linux Distributions:
Ubuntu (Default) Fedora
OpenSUSE

At this point when I type "bash" at the regular Windows command prompt or PowerShell I will be launching my default Linux. I can also just type "Ubuntu" or "Fedora," etc to get a specific one.

If I wanted to test my Linux code (.NET, node, go, ruby, whatever) I could script it from Windows and run my tests on n number of distros. Slick for developers.

TODOs if you have WSL and Bash from earlier betas

If you already have "bash" on your Windows 10 machine and want to move to the "many distros" you'll just install the Ubuntu distro from the store and then move your distro customizations out of the "legacy/beta bash" over to the "new train but beta although getting closer to release WSL." I copied my ~/ folder over to /mnt/c/Users/Scott/Desktop/WSLBackup, then opened Ubuntu and copied my .rc files and whatnot back in. Then I removed my original bash with lxrun /uninstall. Once I've done that, my distro are managed by the store and I can have as many as I like. Other than customizations, it's really easy (like, it's not a big deal and it's fast) to add or remove Linuxes on Windows 10 so fear not. Backup your stuff and this will be a 10 min operation, plus whatever apt-get installs you need to redo. Everything else is the same and you'll still want to continue storing and sharing files via /mnt/c.

NOTE: I did a YouTube video called Editing code and files on Windows Subsystem for Linux on Windows 10 that I'd love if you checked out and shared on social media!

Enjoy!


Sponsor: Seq is simple centralized logging, on your infrastructure, with great support for ASP.NET Core and Serilog. Version 4 adds integrated dashboards and alerts - check it out!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.