how to get the server status programmatically in iis server farm
After installing ARR, I can configure Server Farm (Web Farm) and check server state in IIS Manager. However I could not find any information how to get the server status programmatically. In particular, I am using C (C++). Thanks.
Internet Information Services
.NET
C++
-
Sam Wu-MSFT 7,446 Reputation points • Microsoft Vendor
2023-04-25T07:30:30.16+00:00 @nanoart Do you want to get the server status through C# or C++? if it is C#, you can try the following code:
ServerManager manager= ServerManager.OpenRemote("testserver"); var site = manager.Sites.First(); var status = site.State.ToString();
if it is C++, you can try this code: #include <iostream>
#include"C:/Users/Administrator/Downloads/vcpkg-master/packages/cpprestsdk_x64-windows/include/cpprest/http_client.h" int main()
{
// Create an HTTP client to communicate with the IIS server
web::http::client::http_client client(L"http://<server-name>/api/"); // Send a GET request to the server farm status endpoint
web::http::http_response response = client.request(web::http::methods::GET, L"serverFarms/status").get(); // Check if the response was successful
if (response.status_code() == web::http::status_codes::OK)
{
// Get the response body as a JSON object
web::json::value responseBody = response.extract_json().get(); // Get the server status from the JSON object
auto serverStatus = responseBody.at(L"value").at(0).at(L"status").as_string(); // Print the server status
std::cout << "Server status: " << serverStatus.c_str() << std::endl;
}
else
{
std::cout << "Failed to get server status. Error code: " << response.status_code() << std::endl;
} return 0; -
nanoart 0 Reputation points
2023-04-25T15:29:46.0866667+00:00 Hi, Sam, Thank you for the comment, but it doesn't work in my case. I need to know the Health Status of the backend servers configured in the Server Farm.
Please note the servers
192.168.190.30
and192.168.190.31
are tomcat web servers, not IIS. I tried to useMicrosoft.Web.Management.Arr.dll
, as I think IIS Manager uses this dll, but can't work out. -
nanoart 0 Reputation points
2023-04-25T15:44:39.2066667+00:00 Hi, Sam, Thank you for the comment, but I don't think your sample code will work in my case. I need to know the health status of backend servers configured in web farm (server farm provided by ARR module). Please note the backend servers are Java Tomcat web servers, not IIS servers. I tried to use
Microsoft.Web.Management.Arr.dll
, as I noticed IIS Manager used it to show the info, but couldn't work out the source code. -
Lex Li (Microsoft) 5,492 Reputation points • Microsoft Employee
2023-04-26T06:07:22.18+00:00 Are you familiar with the native API exposed in ahadmin.h? https://learn.microsoft.com/en-us/iis/web-development-reference/native-code-api-reference/application-host-administration-interfaces With them you can easily query IIS configuration and locate
webFarms
section in it. -
nanoart 0 Reputation points
2023-04-26T09:24:36.09+00:00 Thanks Lex,
Actually I explored this header file, I believe it can get something in
C:\Windows\System32\inetsrv\Config\applicationHost.config
, like<webFarms> <webFarm name="das.bletchley19.com" enabled="true"> <server address="192.168.190.30" enabled="true"> <applicationRequestRouting httpPort="8074" httpsPort="8443" /> </server> <server address="192.168.190.31" enabled="true"> <applicationRequestRouting httpPort="8074" httpsPort="8443" /> </server> <applicationRequestRouting> <healthCheck url="http://das.bletchley19.com/healthcheck.htm" /> </applicationRequestRouting> </webFarm> <applicationRequestRouting> <hostAffinityProviderList> <add name="Microsoft.Web.Arr.HostNameRoundRobin" /> </hostAffinityProviderList> </applicationRequestRouting> </webFarms>
But the backend server state, especially the server health state (status) is not in there.
-
Lex Li (Microsoft) 5,492 Reputation points • Microsoft Employee
2023-04-27T04:46:03.7333333+00:00 En, it seems to be the furthest the current IIS API can go to. You might send HTTP requests to IP:port combinations learned from configuration and query the healthy states on your own.
-
nanoart 0 Reputation points
2023-04-27T14:18:00.8+00:00 I can certainly do it myself, but it means I have to do the load balancer myself.
I can get the follow code (by disassembling
Microsoft.Web.Management.Arr.dll
)private static PropertyBag GetServerStateFromElement(ServerElement serverElement, long totalRequests, long totalWeight, ref float totalPercentage, bool isLastElement) { ServerState serverState = new ServerState(); serverState.State = (serverElement.ApplicationRequestRouting.Counters.IsValidElement ? serverElement.ApplicationRequestRouting.Counters.State : State.Unknown); serverState.Address = serverElement.Address; serverState.IsHealthy = serverElement.ApplicationRequestRouting.Counters.IsHealthy; serverState.WeightPercentage = (float)serverElement.ApplicationRequestRouting.Weight / (float)totalWeight; serverState.RequestsPerSecond = serverElement.ApplicationRequestRouting.Counters.RequestPerSecond; serverState.CurrentRequests = serverElement.ApplicationRequestRouting.Counters.CurrentRequests; serverState.TotalRequests = serverElement.ApplicationRequestRouting.Counters.TotalRequests; serverState.FailedRequests = serverElement.ApplicationRequestRouting.Counters.FailedRequests; serverState.BytesSent = serverElement.ApplicationRequestRouting.Counters.BytesSent; serverState.BytesReceived = serverElement.ApplicationRequestRouting.Counters.BytesReceived; serverState.ResponseTime = serverElement.ApplicationRequestRouting.Counters.ResponseTime; if (isLastElement) { serverState.RequestDistributionPercentage = ((totalRequests != 0L) ? (1f - totalPercentage) : 0f); } else { float num = (float)serverState.TotalRequests / (float)totalRequests; serverState.RequestDistributionPercentage = ((totalRequests != 0L) ? num : 0f); totalPercentage += serverState.RequestDistributionPercentage; } if (serverElement.ApplicationRequestRouting.Counters.LastResetTickCount > 0L) { serverState.LastUpdatedElapsedTicks = new long?((long)(Environment.TickCount & int.MaxValue) - serverElement.ApplicationRequestRouting.Counters.LastResetTickCount); } return serverState.InternalState; }
But
ArrModuleService
is an internal class, I couldn't figure out how to utilize it.
Sign in to comment