metric.go 36 KB

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