IIS Application Pool (Windows.plugin) (#19950)
thiagoftsm committed
Mar 27, 2025 at 23:07 UTC
e1f33c0a7a37f4cd44ad9a598c7db252799cd5d4
3 files changed
+619
-9
src/collectors/windows.plugin/metadata.yaml
+64
-1
@@ -1143,6 +1143,69 @@ modules:
1143
chart_type: line
1144
dimensions:
1145
- name: uptime
1146
+ - name: IIS Application Pool
1147
+ description: "These metrics refer to the IIS application pool WAS (Windows Process Activation Service)."
1148
+ labels:
1149
+ - name: app
1150
+ description: The name of the Application Pool.
1151
+ metrics:
1152
+ - name: iis.application_pool_current_status
1153
+ description: IIS App Pool current status
1154
+ unit: "status"
1155
+ chart_type: line
1156
+ dimensions:
1157
+ - name: uninitialized
1158
+ - name: initialized
1159
+ - name: running
1160
+ - name: disabling
1161
+ - name: disabled
1162
+ - name: shutdown_pending
1163
+ - name: delete_pending
1164
+ - name: iis.application_pool_current_worker_processes
1165
+ description: IIS App Pool worker processes currently running
1166
+ unit: "processes"
1167
+ chart_type: line
1168
+ dimensions:
1169
+ - name: running
1170
+ - name: iis.application_pool_worker_processes_created
1171
+ description: IIS App Pool worker processes created
1172
+ unit: "processes/s"
1173
+ chart_type: line
1174
+ dimensions:
1175
+ - name: created
1176
+ - name: iis.application_pool_maximum_worker_processes
1177
+ description: IIS App Pool maximum created worker processes
1178
+ unit: "processes"
1179
+ chart_type: line
1180
+ dimensions:
1181
+ - name: created
1182
+ - name: iis.application_pool_recent_worker_process_failures
1183
+ description: IIS App Pool worker process failures during the rapid-fail protection interval
1184
+ unit: "failures/s"
1185
+ chart_type: line
1186
+ dimensions:
1187
+ - name: failures
1188
+ - name: iis.application_pool_worker_process_failures
1189
+ description: IIS App Pool worker process crashes
1190
+ unit: "failures/s"
1191
+ chart_type: line
1192
+ dimensions:
1193
+ - name: crash
1194
+ - name: ping
1195
+ - name: startup
1196
+ - name: shutdown
1197
+ - name: iis.application_pool_recycles
1198
+ description: IIS App Pool recycles
1199
+ unit: "recycles/s"
1200
+ chart_type: line
1201
+ dimensions:
1202
+ - name: recycles
1203
+ - name: iis.application_pool_uptime
1204
+ description: IIS App Pool uptime
1205
+ unit: "seconds"
1206
+ chart_type: line
1207
+ dimensions:
1208
+ - name: uptime
1209
- meta:
1210
plugin_name: windows.plugin
1211
module_name: PerflibHyperV
@@ -2674,4 +2737,4 @@ modules:
2737
unit: requests/s
2738
chart_type: line
2739
dimensions:
2677
- - name: success
\ No newline at end of file
2740
+ - name: success
src/collectors/windows.plugin/perflib-web-service.c
+543
-8
@@ -93,6 +93,56 @@ struct web_service {
93
COUNTER_DATA IISRequestsOther;
94
};
95
96
+// AD information
97
+struct iis_app {
98
+ RRDSET *st_app_current_application_pool_state;
99
+ RRDDIM *rd_app_current_application_pool_state_uninitialized;
100
+ RRDDIM *rd_app_current_application_pool_state_initialized;
101
+ RRDDIM *rd_app_current_application_pool_state_running;
102
+ RRDDIM *rd_app_current_application_pool_state_disabling;
103
+ RRDDIM *rd_app_current_application_pool_state_disabled;
104
+ RRDDIM *rd_app_current_application_pool_state_shutdown_pending;
105
+ RRDDIM *rd_app_current_application_pool_state_delete_pending;
106
+
107
+ RRDSET *st_app_current_worker_process;
108
+ RRDDIM *rd_app_current_worker_process;
109
+
110
+ RRDSET *st_app_maximum_worker_process;
111
+ RRDDIM *rd_app_maximum_worker_process;
112
+
113
+ RRDSET *st_app_recent_worker_process_failure;
114
+ RRDDIM *rd_app_recent_worker_process_failure;
115
+
116
+ RRDSET *st_app_application_pool_recycles;
117
+ RRDDIM *rd_app_application_pool_recycles;
118
+
119
+ RRDSET *st_app_application_pool_uptime;
120
+ RRDDIM *rd_app_application_pool_uptime;
121
+
122
+ RRDSET *st_app_worker_process_created;
123
+ RRDDIM *rd_app_worker_process_created;
124
+
125
+ RRDSET *st_app_worker_process_failures;
126
+ RRDDIM *rd_app_worker_process_crashes;
127
+ RRDDIM *rd_app_worker_process_ping_failures;
128
+ RRDDIM *rd_app_worker_process_shutdown_failures;
129
+ RRDDIM *rd_app_worker_process_startup_failures;
130
+
131
+ COUNTER_DATA APPCurrentApplicationPoolState;
132
+ COUNTER_DATA APPCurrentApplicationPoolUptime;
133
+ COUNTER_DATA APPCurrentWorkerProcess;
134
+ COUNTER_DATA APPMaximumWorkerProcess;
135
+ COUNTER_DATA APPRecentWorkerProcessFailure;
136
+ COUNTER_DATA APPTimeSinceProcessFailure;
137
+ COUNTER_DATA APPApplicationPoolRecycles;
138
+ COUNTER_DATA APPTotalApplicationPoolUptime;
139
+ COUNTER_DATA APPWorkerProcessCreated;
140
+ COUNTER_DATA APPWorkerProcessFailures;
141
+ COUNTER_DATA APPWorkerProcessPingFailures;
142
+ COUNTER_DATA APPWorkerProcessShutdownFailures;
143
+ COUNTER_DATA APPWorkerProcessStartupFailures;
144
+};
145
+
146
static inline void initialize_web_service_keys(struct web_service *p)
147
{
148
p->IISCurrentAnonymousUser.key = "Current Anonymous Users";
@@ -135,14 +185,45 @@ void dict_web_service_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void
185
initialize_web_service_keys(p);
186
}
187
188
+static inline void initialize_app_pool_keys(struct iis_app *p)
189
+{
190
+ p->APPCurrentApplicationPoolState.key = "Current Application Pool State";
191
+ p->APPCurrentApplicationPoolUptime.key = "Current Application Pool Uptime";
192
+ p->APPCurrentWorkerProcess.key = "Current Worker Processes";
193
+ p->APPMaximumWorkerProcess.key = "Maximum Worker Processes";
194
+ p->APPRecentWorkerProcessFailure.key = "Recent Worker Process Failures";
195
+ p->APPTimeSinceProcessFailure.key = "Time Since Last Worker Process Failure";
196
+ p->APPApplicationPoolRecycles.key = "Total Application Pool Recycles";
197
+ p->APPTotalApplicationPoolUptime.key = "Total Application Pool Uptime";
198
+ p->APPWorkerProcessCreated.key = "Total Worker Processes Created";
199
+ p->APPWorkerProcessFailures.key = "Total Worker Process Failures";
200
+ p->APPWorkerProcessPingFailures.key = "Total Worker Process Ping Failures";
201
+ p->APPWorkerProcessShutdownFailures.key = "Total Worker Process Shutdown Failures";
202
+ p->APPWorkerProcessStartupFailures.key = "Total Worker Process Startup Failures";
203
+}
204
+
205
+void dict_app_pool_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
206
+{
207
+ struct iis_app *p = value;
208
+ initialize_app_pool_keys(p);
209
+}
210
+
211
static DICTIONARY *web_services = NULL;
212
+static DICTIONARY *app_pools = NULL;
213
214
static void initialize(void)
215
{
216
+ // IIS
217
web_services = dictionary_create_advanced(
218
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct web_service));
219
220
dictionary_register_insert_callback(web_services, dict_web_service_insert_cb, NULL);
221
+
222
+ // AD (APP_POOL_WAS)
223
+ app_pools = dictionary_create_advanced(
224
+ DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct iis_app));
225
+
226
+ dictionary_register_insert_callback(app_pools, dict_app_pool_insert_cb, NULL);
227
}
228
229
static bool do_web_services(PERF_DATA_BLOCK *pDataBlock, int update_every)
@@ -656,16 +737,452 @@ static bool do_web_services(PERF_DATA_BLOCK *pDataBlock, int update_every)
737
return true;
738
}
739
659
-int do_PerflibWebService(int update_every, usec_t dt __maybe_unused)
740
+static RRDDIM *app_pool_select_dim(struct iis_app *p, uint32_t selector)
741
{
661
- static bool initialized = false;
742
+ switch (selector) {
743
+ case 1:
744
+ return p->rd_app_current_application_pool_state_uninitialized;
745
+ case 2:
746
+ return p->rd_app_current_application_pool_state_initialized;
747
+ case 3:
748
+ return p->rd_app_current_application_pool_state_running;
749
+ case 4:
750
+ return p->rd_app_current_application_pool_state_disabling;
751
+ case 5:
752
+ return p->rd_app_current_application_pool_state_disabled;
753
+ case 6:
754
+ return p->rd_app_current_application_pool_state_shutdown_pending;
755
+ case 7:
756
+ default:
757
+ return p->rd_app_current_application_pool_state_delete_pending;
758
+ }
759
+}
760
663
- if (unlikely(!initialized)) {
664
- initialize();
665
- initialized = true;
761
+static inline void app_pool_current_state(
762
+ struct iis_app *p,
763
+ PERF_DATA_BLOCK *pDataBlock,
764
+ PERF_OBJECT_TYPE *pObjectType,
765
+ PERF_INSTANCE_DEFINITION *pi,
766
+ int update_every)
767
+{
768
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPCurrentApplicationPoolState)) {
769
+ if (!p->st_app_current_application_pool_state) {
770
+ char id[RRD_ID_LENGTH_MAX + 1];
771
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_current_state", windows_shared_buffer);
772
+ netdata_fix_chart_name(id);
773
+ p->st_app_current_application_pool_state = rrdset_create_localhost(
774
+ "iis",
775
+ id,
776
+ NULL,
777
+ "app pool status",
778
+ "iis.application_pool_current_status",
779
+ "IIS App Pool current status",
780
+ "status",
781
+ PLUGIN_WINDOWS_NAME,
782
+ "PerflibWebService",
783
+ PRIO_IIS_APP_POOL_STATE,
784
+ update_every,
785
+ RRDSET_TYPE_LINE);
786
+
787
+ p->rd_app_current_application_pool_state_uninitialized = rrddim_add(
788
+ p->st_app_current_application_pool_state, "uninitialized", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
789
+
790
+ p->rd_app_current_application_pool_state_initialized =
791
+ rrddim_add(p->st_app_current_application_pool_state, "initialized", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
792
+
793
+ p->rd_app_current_application_pool_state_running =
794
+ rrddim_add(p->st_app_current_application_pool_state, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
795
+
796
+ p->rd_app_current_application_pool_state_disabling =
797
+ rrddim_add(p->st_app_current_application_pool_state, "disabling", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
798
+
799
+ p->rd_app_current_application_pool_state_disabled =
800
+ rrddim_add(p->st_app_current_application_pool_state, "disabled", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
801
+
802
+ p->rd_app_current_application_pool_state_shutdown_pending = rrddim_add(
803
+ p->st_app_current_application_pool_state, "shutdown_pending", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
804
+
805
+ p->rd_app_current_application_pool_state_delete_pending = rrddim_add(
806
+ p->st_app_current_application_pool_state, "delete_pending", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
807
+
808
+ rrdlabels_add(
809
+ p->st_app_current_application_pool_state->rrdlabels,
810
+ "app_pool",
811
+ windows_shared_buffer,
812
+ RRDLABEL_SRC_AUTO);
813
+ }
814
+
815
+#define NETDATA_APP_COOL_TOTAL_STATES (7)
816
+ uint32_t current_state = (uint32_t)p->APPCurrentApplicationPoolState.current.Data;
817
+ for (uint32_t i = 1; i <= NETDATA_APP_COOL_TOTAL_STATES; i++) {
818
+ RRDDIM *dim = app_pool_select_dim(p, i);
819
+ uint32_t value = (current_state == i) ? 1 : 0;
820
+
821
+ rrddim_set_by_pointer(p->st_app_current_application_pool_state, dim, (collected_number)value);
822
+ }
823
+
824
+ rrdset_done(p->st_app_current_application_pool_state);
825
+ }
826
+}
827
+
828
+static inline void app_pool_current_worker_processes(
829
+ struct iis_app *p,
830
+ PERF_DATA_BLOCK *pDataBlock,
831
+ PERF_OBJECT_TYPE *pObjectType,
832
+ PERF_INSTANCE_DEFINITION *pi,
833
+ int update_every)
834
+{
835
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPCurrentWorkerProcess)) {
836
+ if (!p->st_app_current_worker_process) {
837
+ char id[RRD_ID_LENGTH_MAX + 1];
838
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_current_worker_processes", windows_shared_buffer);
839
+ netdata_fix_chart_name(id);
840
+ p->st_app_current_worker_process = rrdset_create_localhost(
841
+ "iis",
842
+ id,
843
+ NULL,
844
+ "app pool worker processes",
845
+ "iis.application_pool_current_worker_processes",
846
+ "IIS App Pool worker processes currently running",
847
+ "processes",
848
+ PLUGIN_WINDOWS_NAME,
849
+ "PerflibWebService",
850
+ PRIO_IIS_APP_POOL_WORKER_PROCESSES_CURRENT,
851
+ update_every,
852
+ RRDSET_TYPE_LINE);
853
+
854
+ p->rd_app_current_worker_process =
855
+ rrddim_add(p->st_app_current_worker_process, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
856
+ rrdlabels_add(
857
+ p->st_app_current_worker_process->rrdlabels, "app_pool", windows_shared_buffer, RRDLABEL_SRC_AUTO);
858
+ }
859
+
860
+ rrddim_set_by_pointer(
861
+ p->st_app_current_worker_process,
862
+ p->rd_app_current_worker_process,
863
+ (collected_number)p->APPCurrentWorkerProcess.current.Data);
864
+
865
+ rrdset_done(p->st_app_current_worker_process);
866
+ }
867
+}
868
+
869
+static inline void app_pool_maximum_worker_processes(
870
+ struct iis_app *p,
871
+ PERF_DATA_BLOCK *pDataBlock,
872
+ PERF_OBJECT_TYPE *pObjectType,
873
+ PERF_INSTANCE_DEFINITION *pi,
874
+ int update_every)
875
+{
876
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPMaximumWorkerProcess)) {
877
+ if (!p->st_app_maximum_worker_process) {
878
+ char id[RRD_ID_LENGTH_MAX + 1];
879
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_maximum_worker_processes", windows_shared_buffer);
880
+ netdata_fix_chart_name(id);
881
+ p->st_app_maximum_worker_process = rrdset_create_localhost(
882
+ "iis",
883
+ id,
884
+ NULL,
885
+ "app pool worker processes",
886
+ "iis.application_pool_maximum_worker_processes",
887
+ "IIS App Pool maximum created worker processes",
888
+ "processes",
889
+ PLUGIN_WINDOWS_NAME,
890
+ "PerflibWebService",
891
+ PRIO_IIS_APP_POOL_WORKER_PROCESSES_MAX,
892
+ update_every,
893
+ RRDSET_TYPE_LINE);
894
+
895
+ p->rd_app_maximum_worker_process =
896
+ rrddim_add(p->st_app_maximum_worker_process, "created", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
897
+ rrdlabels_add(
898
+ p->st_app_maximum_worker_process->rrdlabels, "app_pool", windows_shared_buffer, RRDLABEL_SRC_AUTO);
899
+ }
900
+
901
+ rrddim_set_by_pointer(
902
+ p->st_app_maximum_worker_process,
903
+ p->rd_app_maximum_worker_process,
904
+ (collected_number)p->APPMaximumWorkerProcess.current.Data);
905
+
906
+ rrdset_done(p->st_app_maximum_worker_process);
907
+ }
908
+}
909
+
910
+static inline void app_pool_recent_worker_process_failures(
911
+ struct iis_app *p,
912
+ PERF_DATA_BLOCK *pDataBlock,
913
+ PERF_OBJECT_TYPE *pObjectType,
914
+ PERF_INSTANCE_DEFINITION *pi,
915
+ int update_every)
916
+{
917
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPRecentWorkerProcessFailure)) {
918
+ if (!p->st_app_recent_worker_process_failure) {
919
+ char id[RRD_ID_LENGTH_MAX + 1];
920
+ snprintfz(
921
+ id, RRD_ID_LENGTH_MAX, "application_pool_%s_recent_worker_process_failures", windows_shared_buffer);
922
+ netdata_fix_chart_name(id);
923
+ p->st_app_recent_worker_process_failure = rrdset_create_localhost(
924
+ "iis",
925
+ id,
926
+ NULL,
927
+ "app pool failures",
928
+ "iis.application_pool_recent_worker_process_failures",
929
+ "IIS App Pool worker process failures during the rapid-fail protection interval",
930
+ "failures/s",
931
+ PLUGIN_WINDOWS_NAME,
932
+ "PerflibWebService",
933
+ PRIO_IIS_APP_POOL_WORKER_PROCESS_RECENT_FAILURES,
934
+ update_every,
935
+ RRDSET_TYPE_LINE);
936
+
937
+ p->rd_app_recent_worker_process_failure =
938
+ rrddim_add(p->st_app_recent_worker_process_failure, "failures", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
939
+ rrdlabels_add(
940
+ p->st_app_recent_worker_process_failure->rrdlabels,
941
+ "app_pool",
942
+ windows_shared_buffer,
943
+ RRDLABEL_SRC_AUTO);
944
+ }
945
+
946
+ rrddim_set_by_pointer(
947
+ p->st_app_recent_worker_process_failure,
948
+ p->rd_app_recent_worker_process_failure,
949
+ (collected_number)p->APPRecentWorkerProcessFailure.current.Data);
950
+
951
+ rrdset_done(p->st_app_recent_worker_process_failure);
952
+ }
953
+}
954
+
955
+static inline void app_pool_recycles(
956
+ struct iis_app *p,
957
+ PERF_DATA_BLOCK *pDataBlock,
958
+ PERF_OBJECT_TYPE *pObjectType,
959
+ PERF_INSTANCE_DEFINITION *pi,
960
+ int update_every)
961
+{
962
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPApplicationPoolRecycles)) {
963
+ if (!p->st_app_application_pool_recycles) {
964
+ char id[RRD_ID_LENGTH_MAX + 1];
965
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_recycles", windows_shared_buffer);
966
+ netdata_fix_chart_name(id);
967
+ p->st_app_application_pool_recycles = rrdset_create_localhost(
968
+ "iis",
969
+ id,
970
+ NULL,
971
+ "app pool recycles",
972
+ "iis.application_pool_recycles",
973
+ "IIS App Pool recycles",
974
+ "recycles/s",
975
+ PLUGIN_WINDOWS_NAME,
976
+ "PerflibWebService",
977
+ PRIO_IIS_APP_POOL_RECYCLES,
978
+ update_every,
979
+ RRDSET_TYPE_LINE);
980
+
981
+ p->rd_app_application_pool_recycles =
982
+ rrddim_add(p->st_app_application_pool_recycles, "recycles", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
983
+ rrdlabels_add(
984
+ p->st_app_application_pool_recycles->rrdlabels, "app_pool", windows_shared_buffer, RRDLABEL_SRC_AUTO);
985
+ }
986
+
987
+ rrddim_set_by_pointer(
988
+ p->st_app_application_pool_recycles,
989
+ p->rd_app_application_pool_recycles,
990
+ (collected_number)p->APPApplicationPoolRecycles.current.Data);
991
+
992
+ rrdset_done(p->st_app_application_pool_recycles);
993
+ }
994
+}
995
+
996
+static inline void app_pool_upime(
997
+ struct iis_app *p,
998
+ PERF_DATA_BLOCK *pDataBlock,
999
+ PERF_OBJECT_TYPE *pObjectType,
1000
+ PERF_INSTANCE_DEFINITION *pi,
1001
+ int update_every)
1002
+{
1003
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPTotalApplicationPoolUptime)) {
1004
+ if (p->APPTotalApplicationPoolUptime.current.Frequency != 0) {
1005
+ if (!p->st_app_application_pool_uptime) {
1006
+ char id[RRD_ID_LENGTH_MAX + 1];
1007
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_uptime", windows_shared_buffer);
1008
+ netdata_fix_chart_name(id);
1009
+ p->st_app_application_pool_uptime = rrdset_create_localhost(
1010
+ "iis",
1011
+ id,
1012
+ NULL,
1013
+ "app pool uptime",
1014
+ "iis.application_pool_uptime",
1015
+ "IIS App Pool uptime",
1016
+ "seconds",
1017
+ PLUGIN_WINDOWS_NAME,
1018
+ "PerflibWebService",
1019
+ PRIO_IIS_APP_POOL_TOTAL_UPTIME,
1020
+ update_every,
1021
+ RRDSET_TYPE_LINE);
1022
+
1023
+ p->rd_app_application_pool_uptime =
1024
+ rrddim_add(p->st_app_application_pool_uptime, "uptime", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1025
+ rrdlabels_add(
1026
+ p->st_app_application_pool_uptime->rrdlabels, "app_pool", windows_shared_buffer, RRDLABEL_SRC_AUTO);
1027
+ }
1028
+
1029
+ time_t uptime = (time_t)(p->APPTotalApplicationPoolUptime.current.Time /
1030
+ p->APPTotalApplicationPoolUptime.current.Frequency);
1031
+
1032
+ rrddim_set_by_pointer(
1033
+ p->st_app_application_pool_uptime, p->rd_app_application_pool_uptime, (collected_number)uptime);
1034
+
1035
+ rrdset_done(p->st_app_application_pool_uptime);
1036
+ }
1037
}
1038
+}
1039
668
- DWORD id = RegistryFindIDByName("Web Service");
1040
+static inline void app_pool_worker_processes_created(
1041
+ struct iis_app *p,
1042
+ PERF_DATA_BLOCK *pDataBlock,
1043
+ PERF_OBJECT_TYPE *pObjectType,
1044
+ PERF_INSTANCE_DEFINITION *pi,
1045
+ int update_every)
1046
+{
1047
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPWorkerProcessCreated)) {
1048
+ if (!p->st_app_worker_process_created) {
1049
+ char id[RRD_ID_LENGTH_MAX + 1];
1050
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_worker_processes_created", windows_shared_buffer);
1051
+ netdata_fix_chart_name(id);
1052
+ p->st_app_worker_process_created = rrdset_create_localhost(
1053
+ "iis",
1054
+ id,
1055
+ NULL,
1056
+ "app pool worker processes",
1057
+ "iis.application_pool_worker_processes_created",
1058
+ "IIS App Pool worker processes created",
1059
+ "processes/s",
1060
+ PLUGIN_WINDOWS_NAME,
1061
+ "PerflibWebService",
1062
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESSES_CREATED,
1063
+ update_every,
1064
+ RRDSET_TYPE_LINE);
1065
+
1066
+ p->rd_app_worker_process_created =
1067
+ rrddim_add(p->st_app_worker_process_created, "created", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1068
+ rrdlabels_add(
1069
+ p->st_app_worker_process_created->rrdlabels, "app_pool", windows_shared_buffer, RRDLABEL_SRC_AUTO);
1070
+ }
1071
+
1072
+ rrddim_set_by_pointer(
1073
+ p->st_app_worker_process_created,
1074
+ p->rd_app_worker_process_created,
1075
+ (collected_number)p->APPWorkerProcessCreated.current.Data);
1076
+
1077
+ rrdset_done(p->st_app_worker_process_created);
1078
+ }
1079
+}
1080
+
1081
+static inline void app_pool_worker_process_failures(
1082
+ struct iis_app *p,
1083
+ PERF_DATA_BLOCK *pDataBlock,
1084
+ PERF_OBJECT_TYPE *pObjectType,
1085
+ PERF_INSTANCE_DEFINITION *pi,
1086
+ int update_every)
1087
+{
1088
+ if (perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPWorkerProcessFailures) &&
1089
+ perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPWorkerProcessPingFailures) &&
1090
+ perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPWorkerProcessShutdownFailures) &&
1091
+ perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->APPWorkerProcessStartupFailures)) {
1092
+ if (!p->st_app_worker_process_failures) {
1093
+ char id[RRD_ID_LENGTH_MAX + 1];
1094
+ snprintfz(id, RRD_ID_LENGTH_MAX, "application_pool_%s_worker_process_failures", windows_shared_buffer);
1095
+ netdata_fix_chart_name(id);
1096
+ p->st_app_worker_process_failures = rrdset_create_localhost(
1097
+ "iis",
1098
+ id,
1099
+ NULL,
1100
+ "app pool failures",
1101
+ "iis.application_pool_worker_process_failures",
1102
+ "IIS App Pool worker process failures",
1103
+ "failures/s",
1104
+ PLUGIN_WINDOWS_NAME,
1105
+ "PerflibWebService",
1106
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESS_FAILURES,
1107
+ update_every,
1108
+ RRDSET_TYPE_LINE);
1109
+
1110
+ p->rd_app_worker_process_crashes =
1111
+ rrddim_add(p->st_app_worker_process_failures, "crash", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1112
+ p->rd_app_worker_process_ping_failures =
1113
+ rrddim_add(p->st_app_worker_process_failures, "ping", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1114
+ p->rd_app_worker_process_startup_failures =
1115
+ rrddim_add(p->st_app_worker_process_failures, "startup", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1116
+ p->rd_app_worker_process_shutdown_failures =
1117
+ rrddim_add(p->st_app_worker_process_failures, "shutdown", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1118
+ rrdlabels_add(
1119
+ p->st_app_worker_process_failures->rrdlabels, "app_pool", windows_shared_buffer, RRDLABEL_SRC_AUTO);
1120
+ }
1121
+
1122
+ rrddim_set_by_pointer(
1123
+ p->st_app_worker_process_failures,
1124
+ p->rd_app_worker_process_crashes,
1125
+ (collected_number)p->APPWorkerProcessFailures.current.Data);
1126
+
1127
+ rrddim_set_by_pointer(
1128
+ p->st_app_worker_process_failures,
1129
+ p->rd_app_worker_process_ping_failures,
1130
+ (collected_number)p->APPWorkerProcessPingFailures.current.Data);
1131
+
1132
+ rrddim_set_by_pointer(
1133
+ p->st_app_worker_process_failures,
1134
+ p->rd_app_worker_process_startup_failures,
1135
+ (collected_number)p->APPWorkerProcessStartupFailures.current.Data);
1136
+
1137
+ rrddim_set_by_pointer(
1138
+ p->st_app_worker_process_failures,
1139
+ p->rd_app_worker_process_shutdown_failures,
1140
+ (collected_number)p->APPWorkerProcessShutdownFailures.current.Data);
1141
+
1142
+ rrdset_done(p->st_app_worker_process_failures);
1143
+ }
1144
+}
1145
+
1146
+static bool do_app_pool(PERF_DATA_BLOCK *pDataBlock, int update_every)
1147
+{
1148
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "APP_POOL_WAS");
1149
+ if (!pObjectType)
1150
+ return false;
1151
+
1152
+ PERF_INSTANCE_DEFINITION *pi = NULL;
1153
+ for (LONG i = 0; i < pObjectType->NumInstances; i++) {
1154
+ pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
1155
+ if (!pi)
1156
+ break;
1157
+
1158
+ if (!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
1159
+ strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
1160
+
1161
+ // We are not ploting _Total here, because cloud will group the sites
1162
+ if (strcasecmp(windows_shared_buffer, "_Total") == 0) {
1163
+ continue;
1164
+ }
1165
+
1166
+ struct iis_app *p = dictionary_set(app_pools, windows_shared_buffer, NULL, sizeof(*p));
1167
+ app_pool_current_state(p, pDataBlock, pObjectType, pi, update_every);
1168
+
1169
+ app_pool_current_worker_processes(p, pDataBlock, pObjectType, pi, update_every);
1170
+ app_pool_maximum_worker_processes(p, pDataBlock, pObjectType, pi, update_every);
1171
+ app_pool_worker_processes_created(p, pDataBlock, pObjectType, pi, update_every);
1172
+
1173
+ app_pool_recent_worker_process_failures(p, pDataBlock, pObjectType, pi, update_every);
1174
+ app_pool_worker_process_failures(p, pDataBlock, pObjectType, pi, update_every);
1175
+
1176
+ app_pool_recycles(p, pDataBlock, pObjectType, pi, update_every);
1177
+ app_pool_upime(p, pDataBlock, pObjectType, pi, update_every);
1178
+ }
1179
+
1180
+ return true;
1181
+}
1182
+
1183
+static int iis_web_service(char *name, int update_every, typeof(bool(PERF_DATA_BLOCK *, int)) *routine)
1184
+{
1185
+ DWORD id = RegistryFindIDByName(name);
1186
if (id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
1187
return -1;
1188
@@ -673,7 +1190,25 @@ int do_PerflibWebService(int update_every, usec_t dt __maybe_unused)
1190
if (!pDataBlock)
1191
return -1;
1192
676
- do_web_services(pDataBlock, update_every);
677
-
1193
+ routine(pDataBlock, update_every);
1194
return 0;
1195
}
1196
+
1197
+int do_PerflibWebService(int update_every, usec_t dt __maybe_unused)
1198
+{
1199
+ static bool initialized = false;
1200
+
1201
+ if (unlikely(!initialized)) {
1202
+ initialize();
1203
+ initialized = true;
1204
+ }
1205
+
1206
+ int ret = 0;
1207
+#define TOTAL_NUMBER_OF_FAILURES (2)
1208
+ if (iis_web_service("Web Service", update_every, do_web_services))
1209
+ ret++;
1210
+ if (iis_web_service("APP_POOL_WAS", update_every, do_app_pool))
1211
+ ret++;
1212
+
1213
+ return (ret == TOTAL_NUMBER_OF_FAILURES) ? -1 : 0;
1214
+}
src/collectors/windows.plugin/windows_plugin.h
+12
@@ -46,6 +46,18 @@ enum PERFLIB_PRIO {
46
PRIO_WEBSITE_IIS_LOGON_ATTEMPTS,
47
PRIO_WEBSITE_IIS_UPTIME,
48
49
+ PRIO_IIS_APP_POOL_STATE,
50
+ PRIO_IIS_APP_POOL_WORKER_PROCESSES_CURRENT,
51
+ PRIO_IIS_APP_POOL_WORKER_PROCESSES_MAX,
52
+ PRIO_IIS_APP_POOL_WORKER_PROCESS_RECENT_FAILURES,
53
+ PRIO_IIS_APP_POOL_RECYCLES,
54
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESSES_CREATED,
55
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESS_FAILURES,
56
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESS_PING_FAILURES,
57
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESS_SHUTDOWN_FAILURES,
58
+ PRIO_IIS_APP_POOL_TOTAL_WORKER_PROCESS_STARTUP_FAILURES,
59
+ PRIO_IIS_APP_POOL_TOTAL_UPTIME,
60
+
61
PRIO_MSSQL_USER_CONNECTIONS,
62
63
PRIO_MSSQL_DATABASE_TRANSACTIONS,