JOHN SKEET: Congratulations, Chris. Hi. I'm John Skeet, everyone. Happy International Women's Day. I'm also a software engineer in Google. I have not previously been a software engineer at Microsoft, but I'd like to think I know a bit or two about C#. I too, have written a book, "C# in Depth," now in its third edition. CHRIS SMITH: Oh! Shots fired, snap! JOHN SKEET: Hey. So between us we know and love .NET. And we would like to try to find out in the next 45 minutes just which of these languages is better. You know, I love C# deeply. Chris likes this kind of F# language. So, you know, Chris has a theory which he would like to expound. CHRIS SMITH: A theory? No. This is a scientific rigor that I've been thinking about on how to evaluate a programming language. Because, I mean, we act like friends, but really there's a little bit of conflict here. And it's because– how do you evaluate a programming language? Sure. We could bore you with language features, and usage statistics, and the theory that goes into these.
But there is a much better metric that's easier to use and can harness the power of Google's cloud, and that is Book Covers. So here's an example proof. "Programming F#" and its fat bird, and "C# in Depth" and its dude in– with a guy playing a banjo. If F# is to C#, as fat bird is to guy with banjo, fat birds, while admittedly not super awesome, strictly better than guys with banjos. Ergo, F# is better than C#. Quod erat demonstrandum. That which was proved. Boom. JOHN SKEET: See, he's trying with the Latin. I prefer the original Greek. Hoper edei dexai. That which precisely was required to be proved. Rather better. So we know this is– well, I certainly know– this isn't going to be terribly scientific as a way of judging programming languages. But it is a really good way of demonstrating what we can do with .NET on containers, on Google Cloud Platform. So if you could go to judge a programming book by its cover, you will see a, I would say, fairly terrible web application that Chris and I have written between us in .NET.
And you can judge now– judge now, judge often. Whenever Chris is talking, feel free to just go to the website, judge. And by the end of the talk, we will know definitively which is the better language. CHRIS SMITH: That sounds about right. Now, if you do go and vote at JudgeAProgrammin gBookByItsCover.com, the covers you will see are a little unique. Such as crusher foes with VB.NET, PHP-grade enterprise security, or my personal favorite, All the Cool Kids are Using Go. JOHN SKEET: So what you're saying, Chris, is not only are we providing you value in terms of running .NET, but we're also providing you inspiration for writing your own book in the future. CHRIS SMITH: That's right. As it turns out, the lawyers were not happy with us using the data wonderfully provided by the Internet Archives' Open Library Project, which is a shame. So we all know, again, like John said, that maybe book covers and judging a programming language by it isn't a scientific measure. But it is a great backdrop in which to describe how to deploy .NET applications to containers and run them on the Google Cloud Platform.
So here's what the next 45 minutes or so will be about. First, I'm going to give an introduction to containers and what they mean for, say, a .NET developer. How we can build these containerized apps for the Google Cloud Platform. And then go into specifically the Google App Engine flexible environment and Google Container Engine for running these containers on the cloud. And finally, show all of the wonderful things that Stackdriver diagnostics can allow you to see in terms of insights in your application. So let's start with some wonderful books you can find on our website. You know, "What is a Container" or "Stress-free deployment with Containers". The simplest way to break this down is– think of a container as a way to deploy software. If you have a lot of experience with distributed applications, maybe you used Xcopy, maybe you build Windows Installers, maybe you just use two-gigabyte virtual image disks and ship those around. Well, that's kind of a problem and can be a pain.
It's tedious, error prone. And if you want to really talk about scaling your application, replicating extra copies, maybe have one, 10, 1,000 versions of that running across various machines, you need to have a consistent and reliable mechanism for packaging up your software. And that's what a container is. It's a way to deploy your software and describe it in such a way that it can easily be moved around and ran on different machines without needing to know a lot about the target machine. Now, there some interesting concepts, such as the OS level implementation, or virtualization, or some of the small isolation or security benefits. But for this talk let's just say that containers are a mechanism of deployment. So once you have that container, what do you do with it? How do you run it? If I have a container, what do I do with it? And the beauty of containers is that it doesn't really matter. How the container gets ran, how it scales up or down, shouldn't concern you.
It's just a matter of you have your software, it's in a container, and some other orchestration layer takes care of running it on machines. So if we look at the Google Cloud Platform, you can see all of the options you have for running containers. Let's go from left to right, starting with Google Compute Engine. Google Compute Engine is infrastructure as a service. You have a VM. It's close to the bare metal. You can do whatever you want with that VM, and therein lies all the power and capabilities. You can define how your containers are ran, what orchestration layer you're using. It's wonderful. It does come with a serious drawback, however, in that it gives you all this power, and you have to decide how your software is running and how to orchestrate it. And so it can be kind of a pain. But if you go to Google Container Engine, the unit of deployment there isn't just a VM, but rather how to run a series of containers and expose it in a cluster, organized as internal services or external services.
You're defining how software– you give it your containers and you define how they should be scaled up or rolled out, but not necessarily how they should be scheduled, which specific VM should run which specific container, and so on. And so some of these capabilities of load balancing or rollout are handled by Google Compute Engine, which is implemented essentially as a Google-specific version of Kubernetes, an open source container orchestration software that you'll probably hear a lot about at this conference. And finally, there's Google App Engine, which is the traditional platform as a service. In the past, App Engine would give you a lot of great benefits such as great API's to use, automatic scaling, and so on. The drawback was that you had to run your software in a special sandbox that App Engine would then use. And the biggest drawback, at least for me, was that you couldn't run .NET apps on App Engine. That was, of course, until App Engine Flexible Environment.
That's a feature of App Engine that takes a container and runs that, scales it up, provides many of the other benefits of App Engine, the platform as a service, but you control the software that's being ran. You can specify whatever VM or software you want. So today we have launched a .NET core container that can be ran on Google Container Engine or Google App Engine Flexible Environment, so that you can take .NET applications, run them on the .NET core infrastructure, and scale them out on Google's cloud. So for our talk, we're going to focus on primarily Container Engine and App Engine. So now let's start to look at how we actually go about building an application, a .NET application, and putting it on Google's cloud. Could we switch to the demo machine, please? All right, so I'm going to talk about two tools– Cloud Tools for Visual Studio, and Cloud Tools for PowerShell. Whenever there's a new technology, or framework, or something, it's great. But you've got to learn all these new tools and these new idioms, and it's just a road bump.
And so for Cloud Tools for Visual Studio and Cloud Tools for PowerShell, we're just trying to provide extensions for the tools you already use and love. So John's going to open up the Cloud Explore, which is part of our Visual Studio extension that allows you to browse your cloud platform resources. We launched this in the middle of last year, and then we've just continually been adding more and more resource browsers and visualizers within our extension. With the long term goal of just allowing you to manage a lot of your resources from within the IDE and not needing to switch between the Google Cloud console, your development environment, and so on. And if you're wondering where to get it, you can just go to the Manage Extensions and Updates page in Visual Studio, and just search for Google Cloud. And important to note, we are running with the latest and greatest version of the extension which just came out today. JOHN SKEET: And I installed it this morning. CHRIS SMITH: Right.
So if you type really, really fast, you can run through the same demo on your laptop, in the audience. Although, I would be very impressed if you could do so. So Visual Studio Extensions. That's great. But having an IDE clicking around, it's not for everyone, for every task. And so we also have Cloud Tools for PowerShell as a way to use the command line environment to manipulate your cloud resources. For an interactive sort of session, you can just use the GCloud command, and that's fine. But for things a little more advanced, like automating common tasks, or scripting things, maybe you don't want to break down and write a custom application but just maybe a 100-line PowerShell script. So John's going to show us the commands that are available in the Google Cloud PowerShell module. And this is installed with the Cloud SDK on Windows machines. So you likely already have this available. JOHN SKEET: We will not be going through every single one of these. CHRIS SMITH: Yeah.[AUDIENCE LAUGHS] We have more than 10. JOHN SKEET: We'll just say there's a lot. CHRIS SMITH: Now, for our application, JudgeAProgrammin gBookByItsCover.com, we are storing the book covers on Google Cloud Storage. So let's see what buckets we have on Google Cloud Storage. We can use the Get-GcsBucket command. And Cloud Storage is going to return the strongly-typed bucket objects. These aren't just string representations, these are objects that have time stamps, names, other pieces of metadata. And so you can see in addition to where we're hosting, say, the containers and other pieces of data, the prog-book-covers Bucket, where all the data is stored. Now, we can continue to use these commandlets as objects or whatnot, but conceptually, I think of cloud storage as a really, really, really, big hard drive. And one of the benefits of PowerShell is you can create providers to treat non-file system resources as file systems or something. Why don't you just show it off?
JOHN SKEET: So all we need to do is just change directory to prog-book-covers. And we can just see what's in there as if we were just browsing a local hard disk, and then we could look in, say, covers, and then look in covers//large. CHRIS SMITH: And use the common basic PowerShell commands, and it'll behave as if it is a local file system. Which, to be clear, it is not. Not everything is supported in the PowerShell provider. But if you're just trying to navigate or browse some data, it's much more productive than, say, using these other standard commandlets. But just so we don't spend too much time on PowerShell, we'll show off one more commandlet, which is how to pipeline these results. So by composing different PowerShell commandlets, we can do some advanced transformer query– JOHN SKEET: Can I stop typing while you– CHRIS SMITH: Oh, yes, yes. John has a– JOHN SKEET: It's quite long. CHRIS SMITH: –cheat sheet. What we want to do is see all of the best book covers that we have.
And, of course, that means we need to get all of the book covers from the programming book covers bucket. Those that are in the generated folder, get their name, metadata size. And then filter them such that the metadata's language value is equal to F#. And then output it to a grid view. JOHN SKEET: Oh, there weren't any called just C#. So you've changed it for F#. CHRIS SMITH: You know– JOHN SKEET: Oh, no. I found nothing. I'll tell you what. If we can't find anything, let's just get rid of the where clause. Exactly as you would– right. So there's plenty in there. CHRIS SMITH: Oh. NE– or EQ. Yes. PowerShell semantics, yo. JOHN SKEET: Yo, I'm not a PowerShell developer. So now we see all the C# books. CHRIS SMITH: And this is all just standard PowerShell. You can use these today. It's all great. OK. Enough about the tools, let's start talking about the code. And for that I will have John demo a wonderful application written in a very unwonderful language, C#.[JOHN CHUCKLES] JOHN SKEET: OK. So Chris has been talking for a while, so I hope you've had lots of time to vote. I'll just describe the application just a little bit to start with. So we've got a back-end that is responsible for storing all the votes, returning lists of books, or a random book, et cetera. It just returns stuff with web API, returning it in JSON. And we've got a front-end, all this written in ASP.NET Core, with Razor Views, et cetera, entirely as normal talking to the back-end using HttpClient. And we've got some storage that is sort of away from the application itself. Does any of that, so far, sound like something that would be specifically at a Google Cloud conference? No. It's entirely what you could have written at home before even hearing about Google. It so happens that the application that we've got uses Google Cloud Datastore as its storage. And we've got some little neat tricks using Stackdriver to make it much easier to manage within the cloud.
But I do want to keep emphasizing that this is just ASP.NET Core. So all the learning you've already completed, and there's been a lot to learn recently, let's face it, around what's new in ASP.NET Core, all of that applies immediately to everything we're talking about. So we've got this simple application. If I go back to Solution Explorer, you can tell I'm really old school. I prefer the Visual Studio 6 style of having Solution Explorer on the left instead of on the right. So we've got five projects here. The important ones being back-end, web, and models. And I'll just start that going because it takes a little bit of time to just ramp up the debugger. So this is now just running locally. We can still talk to Cloud Datastore from our local machine. And if I go to– this is the back-end, so this is automatically going to the languages' URL. And this is just going to show us in JSON, using JSON.NET, the data that comes back from the back-end. And I can ask for a random C# book, and it will give us all the relevant information.
I could ask to see the votes, et cetera. Then this is the front-end, and this is all just running locally. So this is all fine. And none of this should be at all surprising. I sometimes try to impress in talks, none of this is impressive yet. So we have an ASP.NET Core application. OK? What comes next, Chris? CHRIS SMITH: Where's the Google App Engine Flexible Environment-specific goo? JOHN SKEET: I'm so glad you asked. Well, we could deploy this to App Engine Flexible Environment without having mentioned Google at all in the code. So literally– and the way I initially tested the application when my colleague Ivan said, hey, we've got to build the Visual Studio extension. Why don't you give it a try? I said, new project– ASP.NET Core application. OK. I will run it locally. Yes. It says, hello, welcome to ASP.NET Core. Deploy to App Engine. And none of that needed any Google stuff at all other than the Visual Studio extension. But let me just right click on a project. I'll stop debugging.
It will detect that it's an ASP.NET Core application. And so enable this– Publish to Google Cloud. I hope that's readable enough to you. And when you click on Publish to Google Cloud, you get the choice of App Engine Flex or Container Engine. When you pick App Engine Flex, all you need to specify is a version name that's automatically filled in for you, whether or not to promote it, which means start directing all the traffic towards it. So if this were some kind of Canary build that you weren't entirely sure about, you want to send 1% of traffic to it to start with, you just not promote it within the IDE here. And you can later on sort of choose how to do your traffic split within the Google Cloud console. And then we can open the site after publishing. So I'm not going to do that. But I will point out a couple of things. We have two services, App Engine really helpfully gives us DNS entries automatically. So we will have ProgrammingBooks ByCovers.appspot.com. But we've got two services.
One of them needs to be the back-end. That's got to be hosted on a different IP address. So how would you do that? Are any of you App Engine developers already? At the back– right. What file would you look at if you wanted to customize your App Engine application? App.yaml, was that– I hope you said app.yaml. I couldn't hear entirely clearly. CHRIS SMITH: That was the right answer. JOHN SKEET: It was the right answer. So here, again, we have an app.yaml. And in this case we're specifying that the runtime is ASP.NET Core. We didn't have to– if you just created your ASP.NET Core completely default project and deployed, you don't need to create this file. The extension will create it explicitly for you if you ask it to. There's another context menu item to say generate me an app.yaml and a Dockerfile. But if you don't need any customization at all, it can just go and generate that in the background, somewhere hidden, and then deploy things, and then it's gone.
But if you do need to customize it, all you need is to specify these two things. And then service back-end just says, we want this back-end. We want this service to be called back-end. And we can see this is actually deployed if we go to backend.programm ingbooksbycover. appspot.com/languages, then we can see exactly the same thing. So that is now code that is running on App Engine Flexible Environment. CHRIS SMITH: And this is one of the benefits of App Engine is that it provides you the DNS automatically. I mean, you probably don't want to have your entire company's website have a .appspot.com address. JOHN SKEET: But for a Friday afternoon experiment, it's really handy. CHRIS SMITH: It's much more convenient than remembering the IP address of some VM and some Kubernetes cluster and so on. JOHN SKEET: And in order to get going with this, all you would have to do– I think you would possibly have to go into Cloud Console and enable App Engine, but that's kind of it.
You don't need to set up a cluster. Whereas for Container Engine, which we'll come onto later on, you do need to go through a step of setting up your cluster. Which has the benefits of allowing you to size it, and say where it is, and all kinds of things that when you want more control, Google can give it to you. When you just say, just deploy the stuff, you can do that, too. OK. So that's running on App Engine. We can make exactly the same code run on Container Engine, as well. And it's the Container Engine version that JudgeAProgrammin gBookByItsCover.com– could you not have chosen some shorter name for this? CHRIS SMITH: No. JOHN SKEET: That site is hooked up to Container Engine. And we can prove that now. So if we go to JudgeAProgrammin gBookByItsCover.com. And we'll just see, I didn't actually show you the details of the app, which is all of this page. And we've got a stats page showing how many– hey, they've been voting. It's great. You must have been speaking for quite a while.
It's good. So we can see that there's the covers. And we can see there's a bit of a mistake in this site at the moment. You see here it says, "Code by Chris Smith and Jon Skeet". OK, so that's clearly the wrong way around. So we're just going to fix that and deploy straight to Container Engine. So all I need to do is find the layout. So this would be common across all pages. And here we go. Here's the "Code by–". Let's give it a bit of emphasis as well. OK. So we're happy. We would obviously normally test it locally. But we can just hit– I haven't even hit Build, because I know that doing Publish will do a build automatically. I don't need to rely on the compiler. I'll just see whether it publishes properly. So Container Engine from the same menu as before. And this time we have a few more things that we can configure. And that's partly because right now this is all you can configure when publishing from Container Engine, from Visual Studio.
So we don't have the equivalent of app.yaml for extra configuration, things like environment variables and whatever. I would hasten to add that this is in the current iteration. We definitely want to expand the range of services and the depth of the experience in each case. And we would very, very much welcome feedback as to how you would particularly want to see that happen and which aspects you want to customize. So I'm going to call it front-end, because I know that that's what my deployment name is called. And here we can choose whether or not to expose a service. So in Kubernetes, a service is a set of replicated containers that all look like one thing to, not necessarily the outside world, but to everything else. So my back-end is a service that is not exposed to the public internet, unlike we saw on appspot.com for the back-end on App Engine Flex. Nothing can get to our back-end on Container Engine, apart from other things within the cluster. So for the back-end, I do still have Exposer service, but I don't take the make-up service public because I'm deploying the front-end now.
We can just hit Publish. Having said, we do want to make it public. CHRIS SMITH: And worth pointing out– this is using an existing cluster that's been set up on Google Container Engine. This is something that I don't believe we have the support for just yet in creating new clusters. JOHN SKEET: Not within Visual Studio. But it's pretty easy. If you know how to use a web browser, you can do it. So while this is deploying– and we can see what it's doing. So it's currently going through all the dotnet publish aspect. So, again, when I was emphasizing– you may get sick of me emphasizing this– this is just regular ASP.NET Core. The whole aim is for you not to have to learn a load of new things. So if it works with dotnet publish, if you've got some extra bit of tooling in your currently project JSON, but obviously in Visual Studio 2017, you'll see as proj, et cetera. We're just saying, hey, ASP.NET Core, could you publish the application, please? And then we're taking those published bits.
We're then sending them up to a cloud container builder. So I don't have anything on my local machine that can build a container image. But that's fine because Google has got our back covered. We can do all of that in the cloud. So that's all happening in the background at the moment. And I said that we don't have much support for configuring really customized bits when you're deploying to Container Engine in Visual Studio. But it really is just using Kubernetes. Just as we're just using ASP.NET Core, we're just using Kubernetes as it's meant to be used. So if you already have Kubernetes set up, and you've got some Ruby, you've got some PHP, you've got some Go, some Python, we're just going to fit in there. You can just deploy a new service, and your other services will be able to talk to it. They'll be able to talk the other way around. And if you want to deploy using Kubectl, which is the sort of common tool for Kubernetes, that's absolutely fine, too.
You can do the same thing that Visual Studio is doing. We're not trying to do anything– it's much easier for us if we don't have to be clever. If we can just use all the smarts that everyone else, whether it's from Microsoft with ASP.NET Core, or our partners and colleagues in the Kubernetes and Container Engine team. If we can use everything they've done, why would we want to build it ourselves? CHRIS SMITH: Show me that slick Kubernetes URI. JOHN SKEET: So we can run– anyone who is using Kubernetes already will know about running Kubectl proxy, which runs its own local web server. So you can see what your application is doing. So we can see that we've got two deployments. If we look at the pods– I'm not going to go into all the details of what pods mean. But, oh, this one's been up. The front-end, our three pods, because it's replicated three times, have been up for about 20 seconds. So it looks like we've padded enough to do all the deployment stuff.
CHRIS SMITH: Huzzah! JOHN SKEET: So we can prove that that's the case by going back to the website. And let's see whether the correction that we've made works. Yep. We can see that now it's in a much more sensible order. Let's just check that the stats page is still working. CHRIS SMITH: And– JOHN SKEET: Hang on. The stats page is taking a bit longer than normal. OK. CHRIS SMITH: But there's a lot of good votes. JOHN SKEET: Yeah. But we just need to hold on for a minute. I'm always a bit distressed when a talk starts going a bit wrong. So I'm just going to have a look and see in the cloud console what's going on when we hit that Votes page. That shouldn't take that long. So we're just going to look into Stackdriver trace. I mentioned Stackdriver earlier on. And I can just look at what's been going on. Let's just look last hour and then zoom in over here. CHRIS SMITH: So the Stackdriver Trace feature allows you to have insights into what's happening behind the scenes in your applications.
For example, making requests to other services, reading and writing from databases. JOHN SKEET: So, for example– hang on Chris, hang on. So, for example, this is a request to our stats page on our front-end. And Chris was just trying to flannel there, so that you couldn't see what was going on in this request. Look at this. So this is requests from our front-end to our back-end. I know– because I wrote most of this code– I know that when we hit the stats page it should ask the back-end, show me the number of votes for each language, and then it can do a bit of aggregation. It should not be fetching a random F# book, a random C# book, and then casting a vote– and doing it 10 times by the looks of it. OK. At this point– CHRIS SMITH: I don't know what you're talking about. JOHN SKEET: Well, at this point, the code cannot lie. We've just deployed the code from this very laptop. CHRIS SMITH: I don't know who has access to that laptop. JOHN SKEET: Yeah. I remember when I went to the restroom, and you seemed to be hovering around.
Let's have a look. So we know it's the book's controller. Is this in the front-end? Yeah. OK. So let's have a look at the stats. OK. I'm so disappointed. Do you know what disappoints me most? It's not the blatant cheating. CHRIS SMITH: Cheating? I'm simply– JOHN SKEET: Look at this. Look at this. We have two operations that are asynchronous operations. And Chris is waiting for the first one to finish before he makes the second one. At least cheat properly, Chris. Look, look. I'll correct the cheating. Task equals this. And then we can do the same for the C# one. And then we can at least do things properly. See, you can tell he's not used to a decent language. There we go. CHRIS SMITH: If only C# had proper support for Monads and computation expressions, instead of this clunky async– JOHN SKEET: Right. Yeah, because that was so clunky, adding two lines just to– ah! Anyway. The point is it was really easy to see what was happening in that specific front-end call.
CHRIS SMITH: So, John, sure. I may or may not have tried to cheat here, OK? Tell me what sort of nefarious contortions you had to do to the code so that you enabled Trace. JOHN SKEET: OK. So, firstly, most importantly, we had to start by installing the NuGet packages. Obviously, the way that you get packages in .NET is with NuGet. So they're all NuGet.org. And if we look at our project .JSON, we'll see we've got a bunch of packages. And in fact, for a couple of reasons I won't go into, there are a few more packages here than you would normally see, or you'd normally need to see, is the data store one and the Google Cloud diagnostics ASP.NET Core. So these aren't yet in beta even, but we're getting there. So once you've installed the packages, then in your start up, because that's where you configure things in ASP.NET Core, all we need to do in configure services is we just say we're going to add Google Trace. And in fact, normally– I added a little bit of a crutch just in case there was so much traffic that we happen not to capture the stats requests that I made.
You can override things to explicitly say, I really want to trace this call, rather than just relying on a 1 QPS sort of statistical aspect. But if you're happy with defaults, it's as simple as just saying, just add Google Trace for this project. And at the same time in the Configure method, I'm saying, yep, I want to use Google Logging. And there are other options you can give. That's logging informational things at the moment. And I also want to use Google Exception Logging. So that's enough to get started for some tracing. But there are two extra bits that I needed to do in order to see this hooking up from the front-end to the back-end. And that's really, I think, where the power is. So we're using HttpClient to make this request. And HttpClient is built so that you can hook in your own listeners, and it's very, very simple. In my JSON back-end, which is very simple code, all we do is we create an HttpClient from a Trace Header Propagating Handler, which is a scary name for what you want to put into an HttpClient.
And that gets just injected by dependency injection as is entirely idiomatic for ASP.NET Core. Have you spotted some kind of pattern here? We want to be very much doing the right thing for the platform that we're working with. So you create an HttpClient. And then when the front-end says, OK, I'm going to create a trace with an ID of blah blah blah. Then when you make any HTTP request with that HttpClient, it's automatically going to add a header that the equivalent code down in the back-end is going to say, ah, I see you've already got that Trace Header. So therefore I will make sure that when I do any tracing to say that I've got the request, or any manual tracing that you're doing, it all attaches it together. Which means you can see what's going on. CHRIS SMITH: Sounds like it's a really complicated way to say, it just works like you want. JOHN SKEET: It just works like you want with very small bits that are well-documented in our samples and things.
The other aspect, as well as hooking front-end to back-end, we're also talking to Datastore. And that hooking isn't currently done automatically. So when I have a Datastore vote repository, I take an IManaged Tracer. And this is all slightly influxed. We're really trying to make things as easy as we possibly can. But all we need say is, oh, just run this action here. So inserting a vote into Datastore, just run that in a Trace span called DatastoreInsertVote. And, for example, when we have the– doing the votes, we need to do two different Datastore operations. We look up a summary of things until recently, and then we do a separate query. So we call RunInSpan again. And if I go back to our cheating Trace, I'll see right at the bottom– oh, no, I think I ran out of space. But I think if I look for stats and try to find it from back when it wasn't cheating– is that a Stats one? I'm not sure why it's not filtering to stats. OK. There we go. So back when it wasn't cheating, so it was a lot quicker.
We can see that we have DataStoreSummary, and we know that that took 14 milliseconds and DataStoreQueryVotes. And these happen to be doing Datastore things. But the point is that it's only because I called RunInSpan. You could be doing whatever you want. You could be talking to completely different services not even on Google, or doing your own internal computation, or calling your InServices, whatever it is. These can nest. It's all beautiful to see what's going on within your requests. So that's one aspect of Stackdriver Diagnostics. But I've already sort of shown you the code to do two other things, which is Error Reporting and Logging. I will briefly show you. People generally know what Logging looks like. So I probably won't go into that other than to say it's probably richer Logging than you're used to. This is because Google has a lot of experience of, you don't want to be looking through 100 different log files for one particular thing just because you've got two replicated services, each with 50 different replicas.
In general, Google Cloud Platform tries to build on the experience that Google's got of– we know how to build software, and we know the problems of building software. So I think you'll find the Logging richer than you may be used to. But the Error Reporting– obviously, my code normally doesn't throw any exceptions, but Chris's code sometimes does. So I've had to explicitly add some breaking things into our application. So we do have two extra URLs that you may not be expecting. One of GoBang that throws an exception directly. And the other one is GoBangBackend, that makes a request to the back-end, and that has another control that will GoBang. So let's just visit both of those URLs. So if we go to GoBang, you'll see I've got the entirely vanilla ASP.NET Core error page. Let's hit it a few times to prove– CHRIS SMITH: Now, I'd like to point out that that code is by John Skeet, first author. [JOHN LAUGHS] JOHN SKEET: And we can do GoBangBackend.
And this time it's not actually a failure response, HTTP response from the front-end, because we expected it to fail. But now that we've had those happen, and we can make them happen a few times, we can go to Stackdriver Error Reporting. And we can see not just those, but everything else that's happened. So we can see, OK, we've got this back-end failure, and we can see that it's happened a few times recently. And once when we were demoing this in prep earlier, and once yesterday when we were prepping. We've got the Bangety Bang Bang Bang, which is the front-end one. We've got KeyNotFoundException, which is Chris Smith not knowing the proper use of Get-hashcode. [CHRIS LAUGHS] I kid you not, and I'm happy to give more details later on in private. But we can see it all. We have the Stack Trace right there. So you can find out what is going on in your application very easily, and that really was– tracing, we had to add a few different things. For Error Reporting, it really was as simple as use Google Exception Logging.
The only thing I would say is you need to make sure you put it in the right place. Previously, I had it there, at which point it did entirely different things because of the way that the middleware of ASP.NET Core works. So if you run into problems with Error Reporting, make sure that your code looks exactly like our sample code. Well, that's the only little detail I'll give in that. CHRIS SMITH: And we should– JOHN SKEET: But it's easy. Well, that's the way that middleware works. So the Use Exception Handler there is going to say, well, I'll just render the Razor View, and there's no longer an exception. So if we get pulled after that, we haven't got anything to report. CHRIS SMITH: Fair enough. JOHN SKEET: It's fine. So with Stackdriver Logging, Stackdriver Error Reporting, and Stackdriver Tracing, there's one aspect to Stackdriver that I haven't even mentioned before, and that's forensic debugging. I don't have anything to show you on that front just yet.
But maybe watch this space. CHRIS SMITH: Boom. Could we cut back to the slides, please? OK. So we did the super-slick demo, awe-inspiring demo, death-defying demo, mind-blowing demo. OK, great, no more demos. Tear. So we covered quite a few products, many tools, and so let's just recap what we've covered today. First, we showed Cloud Tools for Visual Studio and Cloud Tools for PowerShell as extensions to the tools that you're probably using today to build .NET applications. And these are just ways to help make it easier to transition your applications to Google's cloud. Then we covered containers. Today we launched the ASP.NET Core container image that you can then use as a base image to run .NET applications on Google's Cloud Platform, such as App Engine Flexible Environment, or Google Container Engine. And both of those can be deployment targets from within Visual Studio. And then, finally, we showed off some of the, dare I say, sweet, sweet runtime diagnostics that you can get from Stackdriver.
This is all available from just adding a reference to an instrumentation library and just hooking it into your application. You don't need to do a lot of contorting of your application to take advantage of this. Rather, we want to make it as simple as possible. All right. So with that in mind, let us find out the world's best programming language. John, if you could go to JudgeAProgrammin gBookByItsCover.com/Winner. JOHN SKEET: Ah. If we could switch back to the demo machine, please? CHRIS SMITH: And F# sharp wins by like a bazillion! Oh, negative 5 votes, John. Tough break. OK. So obviously this is made up. I just didn't want anyone to feel bad, right? Particularly if the newspaper headline was, "Google declarers random programming language the best in the world." I want you go to– JOHN SKEET: Let's see, winning stats. So these are with the actual votes cast. CHRIS SMITH: And with some alleged– JOHN SKEET: Oh, yeah, with a few– yeah. So in fact, every time that someone's gone to the stats page.
So we can probably ignore 160 of those votes. [CHRIS LAUGHS] And with Logging, we could easily find out how many times people have gone to /stats since we deployed and then just null out those votes. CHRIS SMITH: Yeah, but, you know– JOHN SKEET: In fact, look at this. 161 votes for F# and 165. There's an interesting balance there, I think. CHRIS SMITH: Interesting. Well, we will continue to argue about this probably for the rest of our lives. JOHN SKEET: Oh, we will. CHRIS SMITH: And so unfortunately, maybe we didn't inch mankind closer to world peace. I'm sorry. But at least now we know how we could potentially use the Google Cloud Platform to achieve such a wonderful goal. Could you go back to the slides, please? OK. So there's many other things going on in the Windows .NET Tooling space. First, there are plenty of resources, such as code labs to kind of get some hands-on experience with the tools and technologies. Also the specific landing page for a .NET or Windows.
There's an upcoming talk on Windows tomorrow and about how Windows containers can be exposed, I believe, from Server 2016 on Compute Engine. And then also there's the meet-the-experts for .NET tomorrow, from 1:00 to 4:00. With that I believe we have a few more minutes for questions. JOHN SKEET: Just before questions, I would like a personal request. One of the things that we were talking about before resources was the libraries. I'm personally responsible for the client libraries that I used for Datastore, for example. So if you've used any Google APIs in the past, or even if you haven't, but certainly if you have, and if you found them a bit tricky to use, and sort of seeming to make me lie about being idiomatic with exactly fitting into the C# ways of things, please give the new ones a try. And I would love feedback about it. They're not GA just yet, which means if there's something that needs changing, we can still change it. So please try them and give me feedback.[MUSIC PLAYING]
Google Cloud Platform is great for running ASP.NET workloads and is well-known for its support for containers in App Engine Flex and Kubernetes. In this video, you’ll learn how to deploy and manage your modern .NET apps on GCP. If you like working in .NET, containers, and GCP, this talk is for you.
Missed the conference? Watch all the talks here: https://goo.gl/c1Vs3h
Watch more talks about Application Development here: https://goo.gl/YFgZpl