metric.go 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. // Copyright (C) 2019 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. //go:build !nometrics
  15. // Package metric provides Prometheus metrics support
  16. package metric
  17. import (
  18. "github.com/go-chi/chi/v5"
  19. "github.com/prometheus/client_golang/prometheus"
  20. "github.com/prometheus/client_golang/prometheus/promauto"
  21. "github.com/prometheus/client_golang/prometheus/promhttp"
  22. "github.com/drakkan/sftpgo/v2/internal/version"
  23. )
  24. const (
  25. loginMethodPublicKey = "publickey"
  26. loginMethodKeyboardInteractive = "keyboard-interactive"
  27. loginMethodKeyAndPassword = "publickey+password"
  28. loginMethodKeyAndKeyboardInt = "publickey+keyboard-interactive"
  29. loginMethodTLSCertificate = "TLSCertificate"
  30. loginMethodTLSCertificateAndPwd = "TLSCertificate+password"
  31. loginMethodIDP = "IDP"
  32. )
  33. func init() {
  34. version.AddFeature("+metrics")
  35. }
  36. var (
  37. // dataproviderAvailability is the metric that reports the availability for the configured data provider
  38. dataproviderAvailability = promauto.NewGauge(prometheus.GaugeOpts{
  39. Name: "sftpgo_dataprovider_availability",
  40. Help: "Availability for the configured data provider, 1 means OK, 0 KO",
  41. })
  42. // activeConnections is the metric that reports the total number of active connections
  43. activeConnections = promauto.NewGauge(prometheus.GaugeOpts{
  44. Name: "sftpgo_active_connections",
  45. Help: "Total number of logged in users",
  46. })
  47. // totalUploads is the metric that reports the total number of successful uploads
  48. totalUploads = promauto.NewCounter(prometheus.CounterOpts{
  49. Name: "sftpgo_uploads_total",
  50. Help: "The total number of successful uploads",
  51. })
  52. // totalDownloads is the metric that reports the total number of successful downloads
  53. totalDownloads = promauto.NewCounter(prometheus.CounterOpts{
  54. Name: "sftpgo_downloads_total",
  55. Help: "The total number of successful downloads",
  56. })
  57. // totalUploadErrors is the metric that reports the total number of upload errors
  58. totalUploadErrors = promauto.NewCounter(prometheus.CounterOpts{
  59. Name: "sftpgo_upload_errors_total",
  60. Help: "The total number of upload errors",
  61. })
  62. // totalDownloadErrors is the metric that reports the total number of download errors
  63. totalDownloadErrors = promauto.NewCounter(prometheus.CounterOpts{
  64. Name: "sftpgo_download_errors_total",
  65. Help: "The total number of download errors",
  66. })
  67. // totalUploadSize is the metric that reports the total uploads size as bytes
  68. totalUploadSize = promauto.NewCounter(prometheus.CounterOpts{
  69. Name: "sftpgo_upload_size",
  70. Help: "The total upload size as bytes, partial uploads are included",
  71. })
  72. // totalDownloadSize is the metric that reports the total downloads size as bytes
  73. totalDownloadSize = promauto.NewCounter(prometheus.CounterOpts{
  74. Name: "sftpgo_download_size",
  75. Help: "The total download size as bytes, partial downloads are included",
  76. })
  77. // totalSSHCommands is the metric that reports the total number of executed SSH commands
  78. totalSSHCommands = promauto.NewCounter(prometheus.CounterOpts{
  79. Name: "sftpgo_ssh_commands_total",
  80. Help: "The total number of executed SSH commands",
  81. })
  82. // totalSSHCommandErrors is the metric that reports the total number of SSH command errors
  83. totalSSHCommandErrors = promauto.NewCounter(prometheus.CounterOpts{
  84. Name: "sftpgo_ssh_command_errors_total",
  85. Help: "The total number of SSH command errors",
  86. })
  87. // totalLoginAttempts is the metric that reports the total number of login attempts
  88. totalLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  89. Name: "sftpgo_login_attempts_total",
  90. Help: "The total number of login attempts",
  91. })
  92. // totalNoAuthTried is te metric that reports the total number of clients disconnected
  93. // for inactivity before trying to login
  94. totalNoAuthTried = promauto.NewCounter(prometheus.CounterOpts{
  95. Name: "sftpgo_no_auth_total",
  96. Help: "The total number of clients disconnected for inactivity before trying to login",
  97. })
  98. // totalLoginOK is the metric that reports the total number of successful logins
  99. totalLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  100. Name: "sftpgo_login_ok_total",
  101. Help: "The total number of successful logins",
  102. })
  103. // totalLoginFailed is the metric that reports the total number of failed logins
  104. totalLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  105. Name: "sftpgo_login_ko_total",
  106. Help: "The total number of failed logins",
  107. })
  108. // totalPasswordLoginAttempts is the metric that reports the total number of login attempts
  109. // using a password
  110. totalPasswordLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  111. Name: "sftpgo_password_login_attempts_total",
  112. Help: "The total number of login attempts using a password",
  113. })
  114. // totalPasswordLoginOK is the metric that reports the total number of successful logins
  115. // using a password
  116. totalPasswordLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  117. Name: "sftpgo_password_login_ok_total",
  118. Help: "The total number of successful logins using a password",
  119. })
  120. // totalPasswordLoginFailed is the metric that reports the total number of failed logins
  121. // using a password
  122. totalPasswordLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  123. Name: "sftpgo_password_login_ko_total",
  124. Help: "The total number of failed logins using a password",
  125. })
  126. // totalKeyLoginAttempts is the metric that reports the total number of login attempts
  127. // using a public key
  128. totalKeyLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  129. Name: "sftpgo_public_key_login_attempts_total",
  130. Help: "The total number of login attempts using a public key",
  131. })
  132. // totalKeyLoginOK is the metric that reports the total number of successful logins
  133. // using a public key
  134. totalKeyLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  135. Name: "sftpgo_public_key_login_ok_total",
  136. Help: "The total number of successful logins using a public key",
  137. })
  138. // totalKeyLoginFailed is the metric that reports the total number of failed logins
  139. // using a public key
  140. totalKeyLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  141. Name: "sftpgo_public_key_login_ko_total",
  142. Help: "The total number of failed logins using a public key",
  143. })
  144. // totalTLSCertLoginAttempts is the metric that reports the total number of login attempts
  145. // using a TLS certificate
  146. totalTLSCertLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  147. Name: "sftpgo_tls_cert_login_attempts_total",
  148. Help: "The total number of login attempts using a TLS certificate",
  149. })
  150. // totalTLSCertLoginOK is the metric that reports the total number of successful logins
  151. // using a TLS certificate
  152. totalTLSCertLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  153. Name: "sftpgo_tls_cert_login_ok_total",
  154. Help: "The total number of successful logins using a TLS certificate",
  155. })
  156. // totalTLSCertLoginFailed is the metric that reports the total number of failed logins
  157. // using a TLS certificate
  158. totalTLSCertLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  159. Name: "sftpgo_tls_cert_login_ko_total",
  160. Help: "The total number of failed logins using a TLS certificate",
  161. })
  162. // totalTLSCertAndPwdLoginAttempts is the metric that reports the total number of login attempts
  163. // using a TLS certificate+password
  164. totalTLSCertAndPwdLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  165. Name: "sftpgo_tls_cert_and_pwd_login_attempts_total",
  166. Help: "The total number of login attempts using a TLS certificate+password",
  167. })
  168. // totalTLSCertLoginOK is the metric that reports the total number of successful logins
  169. // using a TLS certificate+password
  170. totalTLSCertAndPwdLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  171. Name: "sftpgo_tls_cert_and_pwd_login_ok_total",
  172. Help: "The total number of successful logins using a TLS certificate+password",
  173. })
  174. // totalTLSCertAndPwdLoginFailed is the metric that reports the total number of failed logins
  175. // using a TLS certificate+password
  176. totalTLSCertAndPwdLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  177. Name: "sftpgo_tls_cert_and_pwd_login_ko_total",
  178. Help: "The total number of failed logins using a TLS certificate+password",
  179. })
  180. // totalInteractiveLoginAttempts is the metric that reports the total number of login attempts
  181. // using keyboard interactive authentication
  182. totalInteractiveLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  183. Name: "sftpgo_keyboard_interactive_login_attempts_total",
  184. Help: "The total number of login attempts using keyboard interactive authentication",
  185. })
  186. // totalInteractiveLoginOK is the metric that reports the total number of successful logins
  187. // using keyboard interactive authentication
  188. totalInteractiveLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  189. Name: "sftpgo_keyboard_interactive_login_ok_total",
  190. Help: "The total number of successful logins using keyboard interactive authentication",
  191. })
  192. // totalInteractiveLoginFailed is the metric that reports the total number of failed logins
  193. // using keyboard interactive authentication
  194. totalInteractiveLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  195. Name: "sftpgo_keyboard_interactive_login_ko_total",
  196. Help: "The total number of failed logins using keyboard interactive authentication",
  197. })
  198. // totalKeyAndPasswordLoginAttempts is the metric that reports the total number of
  199. // login attempts using public key + password multi steps auth
  200. totalKeyAndPasswordLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  201. Name: "sftpgo_key_and_password_login_attempts_total",
  202. Help: "The total number of login attempts using public key + password",
  203. })
  204. // totalKeyAndPasswordLoginOK is the metric that reports the total number of
  205. // successful logins using public key + password multi steps auth
  206. totalKeyAndPasswordLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  207. Name: "sftpgo_key_and_password_login_ok_total",
  208. Help: "The total number of successful logins using public key + password",
  209. })
  210. // totalKeyAndPasswordLoginFailed is the metric that reports the total number of
  211. // failed logins using public key + password multi steps auth
  212. totalKeyAndPasswordLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  213. Name: "sftpgo_key_and_password_login_ko_total",
  214. Help: "The total number of failed logins using public key + password",
  215. })
  216. // totalKeyAndKeyIntLoginAttempts is the metric that reports the total number of
  217. // login attempts using public key + keyboard interactive multi steps auth
  218. totalKeyAndKeyIntLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  219. Name: "sftpgo_key_and_keyboard_int_login_attempts_total",
  220. Help: "The total number of login attempts using public key + keyboard interactive",
  221. })
  222. // totalKeyAndKeyIntLoginOK is the metric that reports the total number of
  223. // successful logins using public key + keyboard interactive multi steps auth
  224. totalKeyAndKeyIntLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  225. Name: "sftpgo_key_and_keyboard_int_login_ok_total",
  226. Help: "The total number of successful logins using public key + keyboard interactive",
  227. })
  228. // totalKeyAndKeyIntLoginFailed is the metric that reports the total number of
  229. // failed logins using public key + keyboard interactive multi steps auth
  230. totalKeyAndKeyIntLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  231. Name: "sftpgo_key_and_keyboard_int_login_ko_total",
  232. Help: "The total number of failed logins using public key + keyboard interactive",
  233. })
  234. // totalIDPLoginAttempts is the metric that reports the total number of
  235. // login attempts using identity providers
  236. totalIDPLoginAttempts = promauto.NewCounter(prometheus.CounterOpts{
  237. Name: "sftpgo_idp_login_attempts_total",
  238. Help: "The total number of login attempts using Identity Providers",
  239. })
  240. // totalIDPLoginOK is the metric that reports the total number of
  241. // successful logins using identity providers
  242. totalIDPLoginOK = promauto.NewCounter(prometheus.CounterOpts{
  243. Name: "sftpgo_idp_login_ok_total",
  244. Help: "The total number of successful logins using Identity Providers",
  245. })
  246. // totalIDPLoginFailed is the metric that reports the total number of
  247. // failed logins using identity providers
  248. totalIDPLoginFailed = promauto.NewCounter(prometheus.CounterOpts{
  249. Name: "sftpgo_idp_login_ko_total",
  250. Help: "The total number of failed logins using Identity Providers",
  251. })
  252. totalHTTPRequests = promauto.NewCounter(prometheus.CounterOpts{
  253. Name: "sftpgo_http_req_total",
  254. Help: "The total number of HTTP requests served",
  255. })
  256. totalHTTPOK = promauto.NewCounter(prometheus.CounterOpts{
  257. Name: "sftpgo_http_req_ok_total",
  258. Help: "The total number of HTTP requests served with 2xx status code",
  259. })
  260. totalHTTPClientErrors = promauto.NewCounter(prometheus.CounterOpts{
  261. Name: "sftpgo_http_client_errors_total",
  262. Help: "The total number of HTTP requests served with 4xx status code",
  263. })
  264. totalHTTPServerErrors = promauto.NewCounter(prometheus.CounterOpts{
  265. Name: "sftpgo_http_server_errors_total",
  266. Help: "The total number of HTTP requests served with 5xx status code",
  267. })
  268. // totalS3Uploads is the metric that reports the total number of successful S3 uploads
  269. totalS3Uploads = promauto.NewCounter(prometheus.CounterOpts{
  270. Name: "sftpgo_s3_uploads_total",
  271. Help: "The total number of successful S3 uploads",
  272. })
  273. // totalS3Downloads is the metric that reports the total number of successful S3 downloads
  274. totalS3Downloads = promauto.NewCounter(prometheus.CounterOpts{
  275. Name: "sftpgo_s3_downloads_total",
  276. Help: "The total number of successful S3 downloads",
  277. })
  278. // totalS3UploadErrors is the metric that reports the total number of S3 upload errors
  279. totalS3UploadErrors = promauto.NewCounter(prometheus.CounterOpts{
  280. Name: "sftpgo_s3_upload_errors_total",
  281. Help: "The total number of S3 upload errors",
  282. })
  283. // totalS3DownloadErrors is the metric that reports the total number of S3 download errors
  284. totalS3DownloadErrors = promauto.NewCounter(prometheus.CounterOpts{
  285. Name: "sftpgo_s3_download_errors_total",
  286. Help: "The total number of S3 download errors",
  287. })
  288. // totalS3UploadSize is the metric that reports the total S3 uploads size as bytes
  289. totalS3UploadSize = promauto.NewCounter(prometheus.CounterOpts{
  290. Name: "sftpgo_s3_upload_size",
  291. Help: "The total S3 upload size as bytes, partial uploads are included",
  292. })
  293. // totalS3DownloadSize is the metric that reports the total S3 downloads size as bytes
  294. totalS3DownloadSize = promauto.NewCounter(prometheus.CounterOpts{
  295. Name: "sftpgo_s3_download_size",
  296. Help: "The total S3 download size as bytes, partial downloads are included",
  297. })
  298. // totalS3ListObjects is the metric that reports the total successful S3 list objects requests
  299. totalS3ListObjects = promauto.NewCounter(prometheus.CounterOpts{
  300. Name: "sftpgo_s3_list_objects",
  301. Help: "The total number of successful S3 list objects requests",
  302. })
  303. // totalS3CopyObject is the metric that reports the total successful S3 copy object requests
  304. totalS3CopyObject = promauto.NewCounter(prometheus.CounterOpts{
  305. Name: "sftpgo_s3_copy_object",
  306. Help: "The total number of successful S3 copy object requests",
  307. })
  308. // totalS3DeleteObject is the metric that reports the total successful S3 delete object requests
  309. totalS3DeleteObject = promauto.NewCounter(prometheus.CounterOpts{
  310. Name: "sftpgo_s3_delete_object",
  311. Help: "The total number of successful S3 delete object requests",
  312. })
  313. // totalS3ListObjectsError is the metric that reports the total S3 list objects errors
  314. totalS3ListObjectsErrors = promauto.NewCounter(prometheus.CounterOpts{
  315. Name: "sftpgo_s3_list_objects_errors",
  316. Help: "The total number of S3 list objects errors",
  317. })
  318. // totalS3CopyObjectErrors is the metric that reports the total S3 copy object errors
  319. totalS3CopyObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  320. Name: "sftpgo_s3_copy_object_errors",
  321. Help: "The total number of S3 copy object errors",
  322. })
  323. // totalS3DeleteObjectErrors is the metric that reports the total S3 delete object errors
  324. totalS3DeleteObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  325. Name: "sftpgo_s3_delete_object_errors",
  326. Help: "The total number of S3 delete object errors",
  327. })
  328. // totalS3HeadObject is the metric that reports the total successful S3 head object requests
  329. totalS3HeadObject = promauto.NewCounter(prometheus.CounterOpts{
  330. Name: "sftpgo_s3_head_object",
  331. Help: "The total number of successful S3 head object requests",
  332. })
  333. // totalS3HeadObjectErrors is the metric that reports the total S3 head object errors
  334. totalS3HeadObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  335. Name: "sftpgo_s3_head_object_errors",
  336. Help: "The total number of S3 head object errors",
  337. })
  338. // totalGCSUploads is the metric that reports the total number of successful GCS uploads
  339. totalGCSUploads = promauto.NewCounter(prometheus.CounterOpts{
  340. Name: "sftpgo_gcs_uploads_total",
  341. Help: "The total number of successful GCS uploads",
  342. })
  343. // totalGCSDownloads is the metric that reports the total number of successful GCS downloads
  344. totalGCSDownloads = promauto.NewCounter(prometheus.CounterOpts{
  345. Name: "sftpgo_gcs_downloads_total",
  346. Help: "The total number of successful GCS downloads",
  347. })
  348. // totalGCSUploadErrors is the metric that reports the total number of GCS upload errors
  349. totalGCSUploadErrors = promauto.NewCounter(prometheus.CounterOpts{
  350. Name: "sftpgo_gcs_upload_errors_total",
  351. Help: "The total number of GCS upload errors",
  352. })
  353. // totalGCSDownloadErrors is the metric that reports the total number of GCS download errors
  354. totalGCSDownloadErrors = promauto.NewCounter(prometheus.CounterOpts{
  355. Name: "sftpgo_gcs_download_errors_total",
  356. Help: "The total number of GCS download errors",
  357. })
  358. // totalGCSUploadSize is the metric that reports the total GCS uploads size as bytes
  359. totalGCSUploadSize = promauto.NewCounter(prometheus.CounterOpts{
  360. Name: "sftpgo_gcs_upload_size",
  361. Help: "The total GCS upload size as bytes, partial uploads are included",
  362. })
  363. // totalGCSDownloadSize is the metric that reports the total GCS downloads size as bytes
  364. totalGCSDownloadSize = promauto.NewCounter(prometheus.CounterOpts{
  365. Name: "sftpgo_gcs_download_size",
  366. Help: "The total GCS download size as bytes, partial downloads are included",
  367. })
  368. // totalGCSListObjects is the metric that reports the total successful GCS list objects requests
  369. totalGCSListObjects = promauto.NewCounter(prometheus.CounterOpts{
  370. Name: "sftpgo_gcs_list_objects",
  371. Help: "The total number of successful GCS list objects requests",
  372. })
  373. // totalGCSCopyObject is the metric that reports the total successful GCS copy object requests
  374. totalGCSCopyObject = promauto.NewCounter(prometheus.CounterOpts{
  375. Name: "sftpgo_gcs_copy_object",
  376. Help: "The total number of successful GCS copy object requests",
  377. })
  378. // totalGCSDeleteObject is the metric that reports the total successful GCS delete object requests
  379. totalGCSDeleteObject = promauto.NewCounter(prometheus.CounterOpts{
  380. Name: "sftpgo_gcs_delete_object",
  381. Help: "The total number of successful GCS delete object requests",
  382. })
  383. // totalGCSListObjectsError is the metric that reports the total GCS list objects errors
  384. totalGCSListObjectsErrors = promauto.NewCounter(prometheus.CounterOpts{
  385. Name: "sftpgo_gcs_list_objects_errors",
  386. Help: "The total number of GCS list objects errors",
  387. })
  388. // totalGCSCopyObjectErrors is the metric that reports the total GCS copy object errors
  389. totalGCSCopyObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  390. Name: "sftpgo_gcs_copy_object_errors",
  391. Help: "The total number of GCS copy object errors",
  392. })
  393. // totalGCSDeleteObjectErrors is the metric that reports the total GCS delete object errors
  394. totalGCSDeleteObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  395. Name: "sftpgo_gcs_delete_object_errors",
  396. Help: "The total number of GCS delete object errors",
  397. })
  398. // totalGCSHeadObject is the metric that reports the total successful GCS head object requests
  399. totalGCSHeadObject = promauto.NewCounter(prometheus.CounterOpts{
  400. Name: "sftpgo_gcs_head_object",
  401. Help: "The total number of successful GCS head object requests",
  402. })
  403. // totalGCSHeadObjectErrors is the metric that reports the total GCS head object errors
  404. totalGCSHeadObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  405. Name: "sftpgo_gcs_head_object_errors",
  406. Help: "The total number of GCS head object errors",
  407. })
  408. // totalAZUploads is the metric that reports the total number of successful Azure uploads
  409. totalAZUploads = promauto.NewCounter(prometheus.CounterOpts{
  410. Name: "sftpgo_az_uploads_total",
  411. Help: "The total number of successful Azure uploads",
  412. })
  413. // totalAZDownloads is the metric that reports the total number of successful Azure downloads
  414. totalAZDownloads = promauto.NewCounter(prometheus.CounterOpts{
  415. Name: "sftpgo_az_downloads_total",
  416. Help: "The total number of successful Azure downloads",
  417. })
  418. // totalAZUploadErrors is the metric that reports the total number of Azure upload errors
  419. totalAZUploadErrors = promauto.NewCounter(prometheus.CounterOpts{
  420. Name: "sftpgo_az_upload_errors_total",
  421. Help: "The total number of Azure upload errors",
  422. })
  423. // totalAZDownloadErrors is the metric that reports the total number of Azure download errors
  424. totalAZDownloadErrors = promauto.NewCounter(prometheus.CounterOpts{
  425. Name: "sftpgo_az_download_errors_total",
  426. Help: "The total number of Azure download errors",
  427. })
  428. // totalAZUploadSize is the metric that reports the total Azure uploads size as bytes
  429. totalAZUploadSize = promauto.NewCounter(prometheus.CounterOpts{
  430. Name: "sftpgo_az_upload_size",
  431. Help: "The total Azure upload size as bytes, partial uploads are included",
  432. })
  433. // totalAZDownloadSize is the metric that reports the total Azure downloads size as bytes
  434. totalAZDownloadSize = promauto.NewCounter(prometheus.CounterOpts{
  435. Name: "sftpgo_az_download_size",
  436. Help: "The total Azure download size as bytes, partial downloads are included",
  437. })
  438. // totalAZListObjects is the metric that reports the total successful Azure list objects requests
  439. totalAZListObjects = promauto.NewCounter(prometheus.CounterOpts{
  440. Name: "sftpgo_az_list_objects",
  441. Help: "The total number of successful Azure list objects requests",
  442. })
  443. // totalAZCopyObject is the metric that reports the total successful Azure copy object requests
  444. totalAZCopyObject = promauto.NewCounter(prometheus.CounterOpts{
  445. Name: "sftpgo_az_copy_object",
  446. Help: "The total number of successful Azure copy object requests",
  447. })
  448. // totalAZDeleteObject is the metric that reports the total successful Azure delete object requests
  449. totalAZDeleteObject = promauto.NewCounter(prometheus.CounterOpts{
  450. Name: "sftpgo_az_delete_object",
  451. Help: "The total number of successful Azure delete object requests",
  452. })
  453. // totalAZListObjectsError is the metric that reports the total Azure list objects errors
  454. totalAZListObjectsErrors = promauto.NewCounter(prometheus.CounterOpts{
  455. Name: "sftpgo_az_list_objects_errors",
  456. Help: "The total number of Azure list objects errors",
  457. })
  458. // totalAZCopyObjectErrors is the metric that reports the total Azure copy object errors
  459. totalAZCopyObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  460. Name: "sftpgo_az_copy_object_errors",
  461. Help: "The total number of Azure copy object errors",
  462. })
  463. // totalAZDeleteObjectErrors is the metric that reports the total Azure delete object errors
  464. totalAZDeleteObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  465. Name: "sftpgo_az_delete_object_errors",
  466. Help: "The total number of Azure delete object errors",
  467. })
  468. // totalAZHeadObject is the metric that reports the total successful Azure head object requests
  469. totalAZHeadObject = promauto.NewCounter(prometheus.CounterOpts{
  470. Name: "sftpgo_az_head_object",
  471. Help: "The total number of successful Azure head object requests",
  472. })
  473. // totalAZHeadObjectErrors is the metric that reports the total Azure head object errors
  474. totalAZHeadObjectErrors = promauto.NewCounter(prometheus.CounterOpts{
  475. Name: "sftpgo_az_head_object_errors",
  476. Help: "The total number of Azure head object errors",
  477. })
  478. // totalSFTPFsUploads is the metric that reports the total number of successful SFTPFs uploads
  479. totalSFTPFsUploads = promauto.NewCounter(prometheus.CounterOpts{
  480. Name: "sftpgo_sftpfs_uploads_total",
  481. Help: "The total number of successful SFTPFs uploads",
  482. })
  483. // totalSFTPFsDownloads is the metric that reports the total number of successful SFTPFs downloads
  484. totalSFTPFsDownloads = promauto.NewCounter(prometheus.CounterOpts{
  485. Name: "sftpgo_sftpfs_downloads_total",
  486. Help: "The total number of successful SFTPFs downloads",
  487. })
  488. // totalSFTPFsUploadErrors is the metric that reports the total number of SFTPFs upload errors
  489. totalSFTPFsUploadErrors = promauto.NewCounter(prometheus.CounterOpts{
  490. Name: "sftpgo_sftpfs_upload_errors_total",
  491. Help: "The total number of SFTPFs upload errors",
  492. })
  493. // totalSFTPFsDownloadErrors is the metric that reports the total number of SFTPFs download errors
  494. totalSFTPFsDownloadErrors = promauto.NewCounter(prometheus.CounterOpts{
  495. Name: "sftpgo_sftpfs_download_errors_total",
  496. Help: "The total number of SFTPFs download errors",
  497. })
  498. // totalSFTPFsUploadSize is the metric that reports the total SFTPFs uploads size as bytes
  499. totalSFTPFsUploadSize = promauto.NewCounter(prometheus.CounterOpts{
  500. Name: "sftpgo_sftpfs_upload_size",
  501. Help: "The total SFTPFs upload size as bytes, partial uploads are included",
  502. })
  503. // totalSFTPFsDownloadSize is the metric that reports the total SFTPFs downloads size as bytes
  504. totalSFTPFsDownloadSize = promauto.NewCounter(prometheus.CounterOpts{
  505. Name: "sftpgo_sftpfs_download_size",
  506. Help: "The total SFTPFs download size as bytes, partial downloads are included",
  507. })
  508. // totalHTTPFsUploads is the metric that reports the total number of successful HTTPFs uploads
  509. totalHTTPFsUploads = promauto.NewCounter(prometheus.CounterOpts{
  510. Name: "sftpgo_httpfs_uploads_total",
  511. Help: "The total number of successful HTTPFs uploads",
  512. })
  513. // totalHTTPFsDownloads is the metric that reports the total number of successful HTTPFs downloads
  514. totalHTTPFsDownloads = promauto.NewCounter(prometheus.CounterOpts{
  515. Name: "sftpgo_httpfs_downloads_total",
  516. Help: "The total number of successful HTTPFs downloads",
  517. })
  518. // totalHTTPFsUploadErrors is the metric that reports the total number of HTTPFs upload errors
  519. totalHTTPFsUploadErrors = promauto.NewCounter(prometheus.CounterOpts{
  520. Name: "sftpgo_httpfs_upload_errors_total",
  521. Help: "The total number of HTTPFs upload errors",
  522. })
  523. // totalHTTPFsDownloadErrors is the metric that reports the total number of HTTPFs download errors
  524. totalHTTPFsDownloadErrors = promauto.NewCounter(prometheus.CounterOpts{
  525. Name: "sftpgo_httpfs_download_errors_total",
  526. Help: "The total number of HTTPFs download errors",
  527. })
  528. // totalHTTPFsUploadSize is the metric that reports the total HTTPFs uploads size as bytes
  529. totalHTTPFsUploadSize = promauto.NewCounter(prometheus.CounterOpts{
  530. Name: "sftpgo_httpfs_upload_size",
  531. Help: "The total HTTPFs upload size as bytes, partial uploads are included",
  532. })
  533. // totalHTTPFsDownloadSize is the metric that reports the total HTTPFs downloads size as bytes
  534. totalHTTPFsDownloadSize = promauto.NewCounter(prometheus.CounterOpts{
  535. Name: "sftpgo_httpfs_download_size",
  536. Help: "The total HTTPFs download size as bytes, partial downloads are included",
  537. })
  538. )
  539. // AddMetricsEndpoint publishes metrics to the specified endpoint
  540. func AddMetricsEndpoint(metricsPath string, handler chi.Router) {
  541. handler.Handle(metricsPath, promhttp.Handler())
  542. }
  543. // TransferCompleted updates metrics after an upload or a download
  544. func TransferCompleted(bytesSent, bytesReceived int64, transferKind int, err error, isSFTPFs bool) {
  545. if transferKind == 0 {
  546. // upload
  547. if err == nil {
  548. totalUploads.Inc()
  549. } else {
  550. totalUploadErrors.Inc()
  551. }
  552. } else {
  553. // download
  554. if err == nil {
  555. totalDownloads.Inc()
  556. } else {
  557. totalDownloadErrors.Inc()
  558. }
  559. }
  560. if bytesReceived > 0 {
  561. totalUploadSize.Add(float64(bytesReceived))
  562. }
  563. if bytesSent > 0 {
  564. totalDownloadSize.Add(float64(bytesSent))
  565. }
  566. if isSFTPFs {
  567. sftpFsTransferCompleted(bytesSent, bytesReceived, transferKind, err)
  568. }
  569. }
  570. // S3TransferCompleted updates metrics after an S3 upload or a download
  571. func S3TransferCompleted(bytes int64, transferKind int, err error) {
  572. if transferKind == 0 {
  573. // upload
  574. if err == nil {
  575. totalS3Uploads.Inc()
  576. } else {
  577. totalS3UploadErrors.Inc()
  578. }
  579. totalS3UploadSize.Add(float64(bytes))
  580. } else {
  581. // download
  582. if err == nil {
  583. totalS3Downloads.Inc()
  584. } else {
  585. totalS3DownloadErrors.Inc()
  586. }
  587. totalS3DownloadSize.Add(float64(bytes))
  588. }
  589. }
  590. // S3ListObjectsCompleted updates metrics after an S3 list objects request terminates
  591. func S3ListObjectsCompleted(err error) {
  592. if err == nil {
  593. totalS3ListObjects.Inc()
  594. } else {
  595. totalS3ListObjectsErrors.Inc()
  596. }
  597. }
  598. // S3CopyObjectCompleted updates metrics after an S3 copy object request terminates
  599. func S3CopyObjectCompleted(err error) {
  600. if err == nil {
  601. totalS3CopyObject.Inc()
  602. } else {
  603. totalS3CopyObjectErrors.Inc()
  604. }
  605. }
  606. // S3DeleteObjectCompleted updates metrics after an S3 delete object request terminates
  607. func S3DeleteObjectCompleted(err error) {
  608. if err == nil {
  609. totalS3DeleteObject.Inc()
  610. } else {
  611. totalS3DeleteObjectErrors.Inc()
  612. }
  613. }
  614. // S3HeadObjectCompleted updates metrics after a S3 head object request terminates
  615. func S3HeadObjectCompleted(err error) {
  616. if err == nil {
  617. totalS3HeadObject.Inc()
  618. } else {
  619. totalS3HeadObjectErrors.Inc()
  620. }
  621. }
  622. // GCSTransferCompleted updates metrics after a GCS upload or a download
  623. func GCSTransferCompleted(bytes int64, transferKind int, err error) {
  624. if transferKind == 0 {
  625. // upload
  626. if err == nil {
  627. totalGCSUploads.Inc()
  628. } else {
  629. totalGCSUploadErrors.Inc()
  630. }
  631. totalGCSUploadSize.Add(float64(bytes))
  632. } else {
  633. // download
  634. if err == nil {
  635. totalGCSDownloads.Inc()
  636. } else {
  637. totalGCSDownloadErrors.Inc()
  638. }
  639. totalGCSDownloadSize.Add(float64(bytes))
  640. }
  641. }
  642. // GCSListObjectsCompleted updates metrics after a GCS list objects request terminates
  643. func GCSListObjectsCompleted(err error) {
  644. if err == nil {
  645. totalGCSListObjects.Inc()
  646. } else {
  647. totalGCSListObjectsErrors.Inc()
  648. }
  649. }
  650. // GCSCopyObjectCompleted updates metrics after a GCS copy object request terminates
  651. func GCSCopyObjectCompleted(err error) {
  652. if err == nil {
  653. totalGCSCopyObject.Inc()
  654. } else {
  655. totalGCSCopyObjectErrors.Inc()
  656. }
  657. }
  658. // GCSDeleteObjectCompleted updates metrics after a GCS delete object request terminates
  659. func GCSDeleteObjectCompleted(err error) {
  660. if err == nil {
  661. totalGCSDeleteObject.Inc()
  662. } else {
  663. totalGCSDeleteObjectErrors.Inc()
  664. }
  665. }
  666. // GCSHeadObjectCompleted updates metrics after a GCS head object request terminates
  667. func GCSHeadObjectCompleted(err error) {
  668. if err == nil {
  669. totalGCSHeadObject.Inc()
  670. } else {
  671. totalGCSHeadObjectErrors.Inc()
  672. }
  673. }
  674. // AZTransferCompleted updates metrics after a Azure upload or a download
  675. func AZTransferCompleted(bytes int64, transferKind int, err error) {
  676. if transferKind == 0 {
  677. // upload
  678. if err == nil {
  679. totalAZUploads.Inc()
  680. } else {
  681. totalAZUploadErrors.Inc()
  682. }
  683. totalAZUploadSize.Add(float64(bytes))
  684. } else {
  685. // download
  686. if err == nil {
  687. totalAZDownloads.Inc()
  688. } else {
  689. totalAZDownloadErrors.Inc()
  690. }
  691. totalAZDownloadSize.Add(float64(bytes))
  692. }
  693. }
  694. // AZListObjectsCompleted updates metrics after a Azure list objects request terminates
  695. func AZListObjectsCompleted(err error) {
  696. if err == nil {
  697. totalAZListObjects.Inc()
  698. } else {
  699. totalAZListObjectsErrors.Inc()
  700. }
  701. }
  702. // AZCopyObjectCompleted updates metrics after a Azure copy object request terminates
  703. func AZCopyObjectCompleted(err error) {
  704. if err == nil {
  705. totalAZCopyObject.Inc()
  706. } else {
  707. totalAZCopyObjectErrors.Inc()
  708. }
  709. }
  710. // AZDeleteObjectCompleted updates metrics after a Azure delete object request terminates
  711. func AZDeleteObjectCompleted(err error) {
  712. if err == nil {
  713. totalAZDeleteObject.Inc()
  714. } else {
  715. totalAZDeleteObjectErrors.Inc()
  716. }
  717. }
  718. // AZHeadObjectCompleted updates metrics after a Azure head object request terminates
  719. func AZHeadObjectCompleted(err error) {
  720. if err == nil {
  721. totalAZHeadObject.Inc()
  722. } else {
  723. totalAZHeadObjectErrors.Inc()
  724. }
  725. }
  726. // sftpFsTransferCompleted updates metrics after an SFTPFs upload or a download
  727. func sftpFsTransferCompleted(bytesSent, bytesReceived int64, transferKind int, err error) {
  728. if transferKind == 0 {
  729. // upload
  730. if err == nil {
  731. totalSFTPFsUploads.Inc()
  732. } else {
  733. totalSFTPFsUploadErrors.Inc()
  734. }
  735. } else {
  736. // download
  737. if err == nil {
  738. totalSFTPFsDownloads.Inc()
  739. } else {
  740. totalSFTPFsDownloadErrors.Inc()
  741. }
  742. }
  743. if bytesReceived > 0 {
  744. totalSFTPFsUploadSize.Add(float64(bytesReceived))
  745. }
  746. if bytesSent > 0 {
  747. totalSFTPFsDownloadSize.Add(float64(bytesSent))
  748. }
  749. }
  750. // HTTPFsTransferCompleted updates metrics after an HTTPFs upload or a download
  751. func HTTPFsTransferCompleted(bytes int64, transferKind int, err error) {
  752. if transferKind == 0 {
  753. // upload
  754. if err == nil {
  755. totalHTTPFsUploads.Inc()
  756. } else {
  757. totalHTTPFsUploadErrors.Inc()
  758. }
  759. totalHTTPFsUploadSize.Add(float64(bytes))
  760. } else {
  761. // download
  762. if err == nil {
  763. totalHTTPFsDownloads.Inc()
  764. } else {
  765. totalHTTPFsDownloadErrors.Inc()
  766. }
  767. totalHTTPFsDownloadSize.Add(float64(bytes))
  768. }
  769. }
  770. // SSHCommandCompleted update metrics after an SSH command terminates
  771. func SSHCommandCompleted(err error) {
  772. if err == nil {
  773. totalSSHCommands.Inc()
  774. } else {
  775. totalSSHCommandErrors.Inc()
  776. }
  777. }
  778. // UpdateDataProviderAvailability updates the metric for the data provider availability
  779. func UpdateDataProviderAvailability(err error) {
  780. if err == nil {
  781. dataproviderAvailability.Set(1)
  782. } else {
  783. dataproviderAvailability.Set(0)
  784. }
  785. }
  786. // AddLoginAttempt increments the metrics for login attempts
  787. func AddLoginAttempt(authMethod string) {
  788. totalLoginAttempts.Inc()
  789. switch authMethod {
  790. case loginMethodPublicKey:
  791. totalKeyLoginAttempts.Inc()
  792. case loginMethodKeyboardInteractive:
  793. totalInteractiveLoginAttempts.Inc()
  794. case loginMethodKeyAndPassword:
  795. totalKeyAndPasswordLoginAttempts.Inc()
  796. case loginMethodKeyAndKeyboardInt:
  797. totalKeyAndKeyIntLoginAttempts.Inc()
  798. case loginMethodTLSCertificate:
  799. totalTLSCertLoginAttempts.Inc()
  800. case loginMethodTLSCertificateAndPwd:
  801. totalTLSCertAndPwdLoginAttempts.Inc()
  802. case loginMethodIDP:
  803. totalIDPLoginAttempts.Inc()
  804. default:
  805. totalPasswordLoginAttempts.Inc()
  806. }
  807. }
  808. func incLoginOK(authMethod string) {
  809. totalLoginOK.Inc()
  810. switch authMethod {
  811. case loginMethodPublicKey:
  812. totalKeyLoginOK.Inc()
  813. case loginMethodKeyboardInteractive:
  814. totalInteractiveLoginOK.Inc()
  815. case loginMethodKeyAndPassword:
  816. totalKeyAndPasswordLoginOK.Inc()
  817. case loginMethodKeyAndKeyboardInt:
  818. totalKeyAndKeyIntLoginOK.Inc()
  819. case loginMethodTLSCertificate:
  820. totalTLSCertLoginOK.Inc()
  821. case loginMethodTLSCertificateAndPwd:
  822. totalTLSCertAndPwdLoginOK.Inc()
  823. case loginMethodIDP:
  824. totalIDPLoginOK.Inc()
  825. default:
  826. totalPasswordLoginOK.Inc()
  827. }
  828. }
  829. func incLoginFailed(authMethod string) {
  830. totalLoginFailed.Inc()
  831. switch authMethod {
  832. case loginMethodPublicKey:
  833. totalKeyLoginFailed.Inc()
  834. case loginMethodKeyboardInteractive:
  835. totalInteractiveLoginFailed.Inc()
  836. case loginMethodKeyAndPassword:
  837. totalKeyAndPasswordLoginFailed.Inc()
  838. case loginMethodKeyAndKeyboardInt:
  839. totalKeyAndKeyIntLoginFailed.Inc()
  840. case loginMethodTLSCertificate:
  841. totalTLSCertLoginFailed.Inc()
  842. case loginMethodTLSCertificateAndPwd:
  843. totalTLSCertAndPwdLoginFailed.Inc()
  844. case loginMethodIDP:
  845. totalIDPLoginFailed.Inc()
  846. default:
  847. totalPasswordLoginFailed.Inc()
  848. }
  849. }
  850. // AddLoginResult increments the metrics for login results
  851. func AddLoginResult(authMethod string, err error) {
  852. if err == nil {
  853. incLoginOK(authMethod)
  854. } else {
  855. incLoginFailed(authMethod)
  856. }
  857. }
  858. // AddNoAuthTried increments the metric for clients disconnected
  859. // for inactivity before trying to login
  860. func AddNoAuthTried() {
  861. totalNoAuthTried.Inc()
  862. }
  863. // HTTPRequestServed increments the metrics for HTTP requests
  864. func HTTPRequestServed(status int) {
  865. totalHTTPRequests.Inc()
  866. if status >= 200 && status < 300 {
  867. totalHTTPOK.Inc()
  868. } else if status >= 400 && status < 500 {
  869. totalHTTPClientErrors.Inc()
  870. } else if status >= 500 {
  871. totalHTTPServerErrors.Inc()
  872. }
  873. }
  874. // UpdateActiveConnectionsSize sets the metric for active connections
  875. func UpdateActiveConnectionsSize(size int) {
  876. activeConnections.Set(float64(size))
  877. }