12

Is there a way to show CPU and RAM usage statistics on an asp.net page. I've tried this code but I have error:

Access to the registry key 'Global' is denied.

on this line:

ramCounter = new PerformanceCounter("Memory", "Available MBytes");
Community
  • 1
  • 1
HasanG
  • 12,734
  • 29
  • 100
  • 154
  • 1
    Have you tried the Process class? ie. `Process.GetCurrentProcess()` and `Process.TotalProcessorTime`? By measuring how much that value grows in a fixed period of time, you can easily figure out how much CPU % you were given/used in that period. I leave this as a comment as I don't know if you would be allowed to check that given the error message you posted. – Lasse V. Karlsen Mar 18 '11 at 19:08
  • Do you have access to the IIS management? If you do, then you can grant your worker pool access to this part of the registry. If not - e.g. if you are on shared hosting - then sorry but you simply don't have access. – Stuart Mar 18 '11 at 19:14
  • @Stuard: I have my own VDS running windows server 2008. Probably the best solution is to write a windows service for this. – HasanG Mar 18 '11 at 20:14

4 Answers4

5

As mentioned in comments, without the appropriate permissions you will not be able to do this. Resource statistics will include a lot of information about processes owned by other users of the system which is privileged information

squillman
  • 13,363
  • 3
  • 41
  • 60
  • I believe you are correct... but could you perhaps provide more info... assume you have run into this yourself and know what permissions are needed and what not.. – Seabizkit Oct 19 '15 at 15:29
5

Use:

    System.Diagnostics.PerformanceCounter cpuUsage = 
      new System.Diagnostics.PerformanceCounter();
    cpuUsage.CategoryName = "Processor"; 
    cpuUsage.CounterName = "% Processor Time";
    cpuUsage.InstanceName = "_Total";

    float f = cpuUsage.NextValue();

Edit:

Windows limits access to the performance counters to those in the Administrators or Performance Logs Users (in Vista+) groups. Setting registry security won't resolve this. It is possible that there is a user right attached to it somewhere.

ukhardy
  • 2,084
  • 1
  • 13
  • 12
  • You need to run `cupUsage.NextValue()` twice...the first time will always result in 0, the second call will return the average CPU usage since the last call. – saluce Apr 29 '14 at 20:48
0

to do not call .NextValue() twice you can use MVC "global variables:

    [AllowAnonymous]
    [HttpGet]
    [ActionName("serverusage")]
    public HttpResponseMessage serverusage()
    {
        try
        {

            PerformanceCounter cpuCounter;

            if (HttpContext.Current.Application["cpuobj"] == null)
            {
                cpuCounter = new PerformanceCounter();
                cpuCounter.CategoryName = "Processor";
                cpuCounter.CounterName = "% Processor Time";
                cpuCounter.InstanceName = "_Total";

                HttpContext.Current.Application["cpuobj"] = cpuCounter;
            }
            else
            {
                cpuCounter = HttpContext.Current.Application["cpuobj"] as PerformanceCounter;
            }

            JToken json;
            try
            {
                json = JObject.Parse("{ 'usage' : '" + HttpContext.Current.Application["cpu"] + "'}");
            }
            catch
            {
                json = JObject.Parse("{ 'usage' : '" + 0 + "'}");
            }

                HttpContext.Current.Application["cpu"] = cpuCounter.NextValue();

            var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
            response.Content = new JsonContent(json);
            return response;

        }
        catch (Exception e)
        {
            var response = Request.CreateResponse(System.Net.HttpStatusCode.BadRequest);
            JToken json = JObject.Parse("{ 'problem' : '" + e.Message + "'}");
            response.Content = new JsonContent(json);
            return response;

        }

    }
}

public class JsonContent : HttpContent { private readonly JToken _value;

    public JsonContent(JToken value)
    {
        _value = value;
        Headers.ContentType = new MediaTypeHeaderValue("application/json");
    }

    protected override Task SerializeToStreamAsync(Stream stream,
        TransportContext context)
    {
        var jw = new JsonTextWriter(new StreamWriter(stream))
        {
            Formatting = Formatting.Indented
        };
        _value.WriteTo(jw);
        jw.Flush();
        return Task.FromResult<object>(null);
    }

    protected override bool TryComputeLength(out long length)
    {
        length = -1;
        return false;
    }
}
-2

Use:

new PerformanceCounter("Processor Information", "% Processor Time", "_Total");

Instead of:

new PerformanceCounter("Processor", "% Processor Time", "_Total");
Sicco
  • 6,167
  • 5
  • 45
  • 61
  • 1
    Why should do OP do this? Please explain! – markus Dec 11 '12 at 23:06
  • This doesn't really help. What this does, though, is gives information if there are multiple physical processors (CPUs) on the motherboard with multiple, possibly hyperthreaded, cores. Instance names are given as `0,0` to indicate the first core on the first CPU, or `1,_Total` to indicate the average for the second CPU, as well as `_Total` for the entire cluster of CPUs. It gives a bit more information about the physical processing capability, but it doesn't give anything to help with the original question. – saluce Apr 29 '14 at 19:16
  • HOW does EITHER of those solve **"Access to the registry key 'Global' is denied."** ? – Seabizkit Oct 19 '15 at 17:07