views:

163

answers:

2

Hi folks, is there a built-in property in any of the ASP.net classes that determines what the uptime of the webserver, where the webapplication is running on, is?

These are some of the possibilities that popped into my mind:

  • global.asax and the Application_OnStart Event. Get the timestamp and to determine the uptime, I just substract it from DateTime.Now
  • Write a windows service (automatically startup) which's only purpose is to store the value of the service start somewhere

But neither of these two offer a "built-in" solution. Is there something I might oversee in the .net framework?

+3  A: 

To get system uptime, use the following code:

TimeSpan uptime;
using (var uptimeCounter = new PerformanceCounter("System", "System Up Time")) {
    uptimeCounter.NextValue();
    uptime = TimeSpan.FromSeconds(uptimeCounter.NextValue());
}

EDIT: Note that this can't be used by partially trusted code.
You could use TimeSpan.FromMilliseconds(Environment.TickCount), but it'll wrap after two weeks.


I wrote a server status page in ASP.Net which shows server uptime and more.
Here is the entire page:

<%@ Page Title="Server Stats" Language="C#" MasterPageFile="~/Admin.Master" AutoEventWireup="true"
    CodeFile="Stats.aspx.cs" Inherits="Stats" %>

<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="Microsoft.VisualBasic.Devices" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
    <style type="text/css">
     body {
      background-color: #9DC0E4;
     }
     table.Details {
      width: 550px;
      margin-left: -275px;
      left: 50%;
      position: absolute;
     }
     table.Details tbody.Group {
      border-bottom: solid black 2px;
      margin-bottom: 15px;
     }
     table.Details th.Group {
      font-size: x-large;
      border-bottom: dashed 1px navy;
     }
     table.Details th.Name {
      text-align: left;
     }
     table.Details td.Value {
      text-align: right;
     }
    </style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <%
     var computer = new ComputerInfo();
     using (var iis = Process.GetCurrentProcess())
     using (var cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total"))
     using (var uptime = new PerformanceCounter("System", "System Up Time")) {
      cpu.NextValue();
      uptime.NextValue();
    %>
    <table class="Details">
     <tbody class="Group">
      <tr>
       <th class="Group" colspan="2">Environment</th>
      </tr>
      <tr>
       <th class="Name">Local server time</th>
       <td class="Value">
        <%= DateTime.Now.ToString("F")%></td>
      </tr>
      <tr>
       <th class="Name">OS</th>
       <td class="Value">
        <%= computer.OSFullName%><br />
        <%= Environment.OSVersion.ToString()%></td>
      </tr>
      <tr>
       <th class="Name">Machine name</th>
       <td class="Value">
        <%= Environment.MachineName%></td>
      </tr>
      <tr>
       <th class="Name">User name</th>
       <td class="Value">
        <%= Environment.UserName%></td>
      </tr>
      <tr>
       <th class="Name">Windows domain</th>
       <td class="Value">
        <%= Environment.UserDomainName%></td>
      </tr>
     </tbody>
     <tbody class="Group">
      <tr>
       <th class="Group" colspan="2">IIS</th>
      </tr>
      <tr>
       <th class="Name">IIS Uptime</th>
       <td class="Value">
        <%= (DateTime.Now- iis.StartTime).ToApproximateString()%></td>
      </tr>
      <tr>
       <th class="Name">Priority</th>
       <td class="Value">
        <%= iis.PriorityClass%></td>
      </tr>
      <tr>
       <th class="Name">Physical Memory Used</th>
       <td class="Value">
        <%= ToSizeString(iis.WorkingSet64)%></td>
      </tr>
      <tr>
       <th class="Name">Virtual Memory Used</th>
       <td class="Value">
        <%= ToSizeString(iis.VirtualMemorySize64)%></td>
      </tr>
     </tbody>
     <tbody class="Group">
      <tr>
       <th class="Group" colspan="2">Hardware</th>
      </tr>
      <tr>
       <th class="Name">Processors</th>
       <td class="Value">
        <%= Environment.ProcessorCount.ToString()%></td>
      </tr>
      <tr>
       <th class="Name">Physical memory</th>
       <td class="Value">
        <%= ToSizeString(computer.TotalPhysicalMemory)%></td>
      </tr>
      <tr>
       <th class="Name">Virtual memory</th>
       <td class="Value">
        <%= ToSizeString(computer.TotalVirtualMemory)%></td>
      </tr>
     </tbody>
     <tbody class="Group">
      <tr>
       <th class="Group" colspan="2">Performance</th>
      </tr>
      <tr>
       <th class="Name">Uptime</th>
       <td class="Value">
        <%= TimeSpan.FromSeconds(uptime.NextValue()).ToApproximateString()%>
       </td>
      </tr>
      <tr>
       <th class="Name">CPU Usage</th>
       <td class="Value">
        <%= (cpu.NextValue()/100).ToString("p")%>
       </td>
      </tr>
      <tr>
       <th class="Name">Physical memory free</th>
       <td class="Value">
        <%= ToSizeString(computer.AvailablePhysicalMemory)%></td>
      </tr>
      <tr>
       <th class="Name">Virtual memory free</th>
       <td class="Value">
        <%= ToSizeString(computer.AvailableVirtualMemory)%></td>
      </tr>
     </tbody>
    </table>
    <%} %>
</asp:Content>

ToSizeString is defined in the .cs file:

protected static string ToSizeString(double bytes) {
 var culture = CultureInfo.CurrentUICulture;
 const string format = "#,0.0";

 if (bytes < 1024)
  return bytes.ToString("#,0", culture);
 bytes /= 1024;
 if (bytes < 1024)
  return bytes.ToString(format, culture) + " KB";
 bytes /= 1024;
 if (bytes < 1024)
  return bytes.ToString(format, culture) + " MB";
 bytes /= 1024;
 if (bytes < 1024)
  return bytes.ToString(format, culture) + " GB";
 bytes /= 1024;
 return bytes.ToString(format, culture) + " TB";
}

ToApproximateString is an extension method defined elsewhere:

public static string ToApproximateString(this TimeSpan time) {
 if (time.TotalDays > 14)
  return ((int)(time.TotalDays / 7)).ToString("#,0.0") + " weeks";
 if (14 - time.TotalDays < .75)
  return "two weeks";
 if (time.TotalDays > 1)
  return time.TotalDays.ToString("#,0.0") + " days";
 else if (time.TotalHours > 1)
  return time.TotalHours.ToString("#,0.0") + " hours";
 else if (time.TotalMinutes > 1)
  return time.TotalMinutes.ToString("#,0.0") + " minutes";
 else
  return time.TotalSeconds.ToString("#,0.0") + " seconds";
}
SLaks
What trust must this run under? Nice solution by the way. +1
Clarence Klopfstein
It runs fine on my host (LFC).
SLaks
`PerformanceCounter` cannot be used by partially trusted code.
SLaks
`Process` also can't be used by partially trusted code.
SLaks
A: 

Thanks, that was the kind of answer I was looking for =)

I'll stick to

TimeSpan _diff = DateTime.Now.Subtract(Process.GetCurrentProcess().StartTime);
this.litRuntime.Text = string.Format("{0} days and {1:00}:{2:00}:{3:00}", (int)_diff.TotalDays, _diff.Hours, _diff.Minutes, _diff.Seconds);

for the moment.

citronas
This will not give you the computer's uptime.
SLaks
On my production server, this gives 1.1 days, whereas the server uptime is 3 weeks.
SLaks