U mfd@sXddlZddlmZddlZddlmZddlZddlZddlm Z ddl Z ddl Z ddl Z ddl mZmZmZmZmZmZmZmZddlmZddlmZmZmZddlmZmZmZm Z m!Z!m"Z"dd l#m$Z$m%Z%m&Z&d d l'm(Z'd d l)m*Z*m+Z+d d l,m-Z-dZ.dZ/Gddde Z0ddZ1e+dfe*e2edddZ3Gddde%Z4Gddde e&Z5ddZ6dSe7e7e8ee7ee7e2e j9ddd Z:d!e+dddde j;dfe8e7e*ee7ee7ee7ee7e8e2ee&e je+fe*e?d%d&d'Z@e7eee*ge?fe7fd(d)d*ZAe7e2d+d,d-ZBGd.d/d/eZCe7e*dd0d1d2ZDe7e7eeEeee7e7fe?eeeFfegdfd3d4d5ZGe7e7eeEeee7e7fe?egdfd6d7d8ZHe7e7eeEeee7e7fe?egdfd6d9d:ZIdTe7e7eeEeee7e7fe?ee7ee7egdfd;d d?d@ZLddAeHfe7e7e*eee7efeeEeddBdCdDZMddAeHfe7e7ee*eee7efeeEeddBdEdFZNddAeHfe7e7eee7efeeEeddGdHdIZOe7e7e7ee*eee7efeeEeddJdKdLZPdMdNZQee7efdOdPdQZRd dRlSmTZTdS)UN)closing)BaseHTTPRequestHandler)ThreadingMixIn)AnyCallableDictListOptionalSequenceTupleUnion) HTTPError)parse_qs quote_plusurlparse) BaseHandler build_opener HTTPHandlerHTTPRedirectHandler HTTPSHandlerRequest) make_serverWSGIRequestHandler WSGIServer) exposition)CollectorRegistryREGISTRY)floatToGoString) CONTENT_TYPE_LATESTdelete_from_gatewaygenerate_latestinstance_ip_grouping_key make_asgi_app make_wsgi_appMetricsHandlerpush_to_gatewaypushadd_to_gatewaystart_http_serverstart_wsgi_serverwrite_to_textfilez(text/plain; version=0.0.4; charset=utf-8c@seZdZdZddZdS)_PrometheusRedirectHandleraw Allow additional methods (e.g. PUT) and data forwarding in redirects. Use of this class constitute a user's explicit agreement to the redirect responses the Prometheus client will receive when using it. You should only use this class if you control or otherwise trust the redirect behavior involved and are certain it is safe to full transfer the original request (method and data) to the redirected URL. For example, if you know there is a cosmetic URL redirect in front of a local deployment of a Prometheus server, and all redirects are safe, this is the class to use to handle redirects in that case. The standard HTTPRedirectHandler does not forward request data nor does it allow redirected PUT requests (which Prometheus uses for some operations, for example `push_to_gateway`) because these cannot generically guarantee no violations of HTTP RFC 2616 requirements for the user to explicitly confirm redirects that could have unexpected side effects (such as rendering a PUT request non-idempotent or creating multiple resources not named in the original request). c Cslt|d|}|dkr |dksB|dkr0|dksBt|j||||t|dd|j|jd|jd }||_ |S) a Apply redirect logic to a request. See parent HTTPRedirectHandler.redirect_request for parameter info. If the redirect is disallowed, this raises the corresponding HTTP error. If the redirect can't be determined, return None to allow other handlers to try. If the redirect is allowed, return the new request. This method specialized for the case when (a) the user knows that the redirect will not cause unacceptable side effects for any request method, and (b) the user knows that any request data should be passed through to the redirect. If either condition is not met, this should not be used. method)-./i3)GETHEAD)r-r.r/)POSTPUT z%20T)headersorigin_req_host unverifiabledata) getattr get_methodr full_urlrreplacer5r6r8r,) selfreqfpcodemsgr5newurlmZ new_requestrDJ/opt/hc_python/lib/python3.8/site-packages/prometheus_client/exposition.pyredirect_requestAs  z+_PrometheusRedirectHandler.redirect_requestN)__name__ __module__ __qualname____doc__rFrDrDrDrEr++sr+c Cs^t|\}}d|kr"||d}||}d|fg}|sTt|rTt|}|dd||fS)zBake output for metrics output.zname[] Content-Type)zContent-Encodinggzip200 OK)choose_encoderZrestricted_registry gzip_acceptedrLcompressappend) registry accept_headeraccept_encoding_headerparamsdisable_compressionencoder content_typeoutputr5rDrDrE _bake_outputbs     rZF)rRrVreturncsfdd}|S)z;Create a WSGI app which serves the metrics from a registry.csf|d}|d}t|dd}|ddkr@d}dg}d }nt|||\}}}||||gS) NZ HTTP_ACCEPTZHTTP_ACCEPT_ENCODINGZ QUERY_STRINGZ PATH_INFOz /favicon.icorM)r\r\)getrrZ)environZstart_responserSrTrUstatusr5rYrVrRrDrEprometheus_appts    z%make_wsgi_app..prometheus_apprD)rRrVrbrDrarEr$qsr$c@seZdZdZddZdS)_SilentHandlerz(WSGI handler that does not log requests.cGsdSz Log nothing.NrDr=formatargsrDrDrE log_messagesz_SilentHandler.log_messageN)rGrHrIrJrhrDrDrDrErcsrcc@seZdZdZdZdS)ThreadingWSGIServerzThread per request HTTP server.TN)rGrHrIrJdaemon_threadsrDrDrDrErisricCs8tj||tjtjd}tt|\}}}}}||dfS)z8Automatically select address family depending on address)typeflagsr)socket getaddrinfo SOCK_STREAM AI_PASSIVEnextiter)addressportinfosfamily_ZsockaddrrDrDrE_get_best_familysrx)certfilekeyfileprotocolcafilecapathclient_auth_requiredr[c CsDtj|d}|dk s|dk r|z|||Wqtk rx}z.t|}t|} |d|d|d| W5d}~XYqXnVz|jtjjdWn@tk r}z"t|}t|} |d| W5d}~XYnX|rtj |_ z|j ||dWnNtk r>}z.t|}t|} |d |d |d| W5d}~XYnX|S) zLoad context supports SSL.r{Nz+Cannot load CA certificate chain from file z or directory z: )purposez*Cannot load default CA certificate chain: ryrzz$Cannot load server certificate file z or its private key file ) ssl SSLContextload_verify_locationsIOErrorrkstrload_default_certsPurpose CLIENT_AUTH CERT_REQUIRED verify_modeload_cert_chain) ryrzr{r|r}r~Zssl_cxtexcexc_typerArDrDrE _get_ssl_ctxs. . ,rz0.0.0.0) rtaddrrRryrz client_cafile client_capathr{r~r[c CsGdddt} t||\| _}t|} t||| | td} |rf|rft||||||} | j| jdd| _t j | j d} d| _ | | | fS)z?Starts a WSGI server for prometheus metrics as a daemon thread.c@seZdZdZdS)z$start_wsgi_server..TmpServerz|dkrP|d}d}n(|dkr^d}n|d krld }n |d krxd }|d ||jdddd|d|d|di}|jD]F}dD].}|j|j|kr||g||qq|||qWn:t k rB} z| j p&d|f| _ W5d} ~ XYnXt | D]T\}} |d|j||jdddd|d|j|d| | qPqd|dS)zHReturns the metrics from the registry in latest text format as a string.cSsx|jr,ddddt|jD}nd}d}|jdk rXdtt|jdd}|j|dt |j |d S) Nz{{{0}}},c Ss4g|],\}}d||ddddddqS)z{}="{}"\\\ \n"z\")rfr<.0kvrDrDrE s z8generate_latest..sample_line..r\r4idr) labelsrfjoinsorteditems timestampintfloatnamervalue)lineZlabelstrrrDrDrE sample_lines  z$generate_latest..sample_linecounterZ_totalinfo_infoZgaugeZstatesetZgaugehistogramZ histogramunknownZuntypedz # HELP {} {} rrrrz# TYPE r4)Z_createdZ_gsumZ_gcount)r\Nz# HELP {}{} {} z gauge r\utf-8)ZcollectrrkrQrf documentationr<Zsamples setdefault Exceptionrgrrextendrencode) rRrrYZmetricZmnamemtypeZ om_samplesssuffix exceptionlinesrDrDrEr!sN  r!)rSr[cCsF|pd}|dD]*}|dddkrtjtjfSqttfS)Nr\r;rzapplication/openmetrics-text)splitstrip openmetricsr!r)rSacceptedrDrDrErN)s rN)rTr[cCs<|pd}|dD]$}|dddkrdSqdS)Nr\rrrrLTF)rrlower)rTrrDrDrErO2s rOc@sReZdZUdZeZeed<ddddZe e dddd Z e ee d d d ZdS) r%z2HTTP handler that gives metrics from ``REGISTRY``.rRNr[c Cs|j}|jd}|jd}tt|jj}t||||d\}}}|t | dd|D]}|j |q`| |j |dS)NAcceptzAccept-EncodingFr4r)rRr5r^rrpathqueryrZZ send_responserrZ send_headerZ end_headerswfilewrite) r=rRrSrTrUr`r5rYheaderrDrDrEdo_GET>s   zMetricsHandler.do_GET)rfrgr[cGsdSrdrDrerDrDrErhMszMetricsHandler.log_messagercCs"t|j}t||tfd|i}|S)zWReturns a dynamic MetricsHandler class tied to the passed registry. rR)rrGrkobject)clsrRcls_nameZMyMetricsHandlerrDrDrEfactoryPs  zMetricsHandler.factory)rGrHrIrJrrRr__annotations__rrrrh classmethodrkrrDrDrDrEr%:s  r%)rrRr[c Csj|dtdtj}t|d}|t|W5QRXtjdkrZt ||n t ||dS)zWrite metrics to the given path. This is intended for use with the Node exporter textfile collector. The path must end in .prom for the textfile collector to process it..wbntN) osgetpidrcurrent_threadidentopenrr!rr<rename)rrRZtmppathfrDrDrEr*`s   r*)urlr,timeoutr5r8 base_handlerr[cs ddfdd }|S)Nrcsltd}fdd|_D]\}}|||qtj|d}|jdkrhtd|jd|jdS)N)r8csS)NrDrD)r,rDrEzr]z/_make_handler..handle..)rizerror talking to pushgateway: r4)rr: add_headerrrr@OSErrorrA)requestrrresprr8r5r,rrrDrEhandlexs   z_make_handler..handlerD)rr,rr5r8rrrDrrE _make_handlerps r)rr,rr5r8r[cCst|||||tS)zDefault handler that implements HTTP/HTTPS connections. Used by the push_to_gateway functions. Can be re-used by other handlers.)rrrr,rr5r8rDrDrEdefault_handlers rcCst|||||tS)a Handler that automatically trusts redirect responses for all HTTP methods. Augments standard HTTPRedirectHandler capability by permitting PUT requests, preserving the method upon redirect, and passing through all headers and data from the original request. Only use this handler if you control or trust the source of redirect responses you encounter when making requests via the Prometheus client. This handler will simply repeat the identical request, including same method and data, to the new redirect URL.)rr+rrDrDrEpassthrough_redirect_handlersr)rr,rr5r8usernamepasswordr[csfdd}|S)zHandler that implements HTTP/HTTPS connections with Basic Auth. Sets auth headers using supplied 'username' and 'password', if set. Used by the push_to_gateway functions. Can be re-used by other handlers.csXdk rBdk rBd}t|}d|}d|ftdS)z1Handler that implements HTTP Basic Auth. N:sBasic Authorization)rbase64 b64encoderQr)Z auth_valueZ auth_token auth_headerr8r5r,rrrrrDrErs  z"basic_auth_handler..handlerD)rr,rr5r8rrrrDrrEbasic_auth_handlers r) rr,rr5r8ryrzr|r{insecure_skip_verifyr[c Csdtj|d} |dk r | |n| | r:d| _tj| _| j||dt| d} t |||||| S)aLHandler that implements an HTTPS connection with TLS Auth. The default protocol (ssl.PROTOCOL_TLS_CLIENT) will also enable ssl.CERT_REQUIRED and SSLContext.check_hostname by default. This can be disabled by setting insecure_skip_verify to True. Both this handler and the TLS feature on pushgateay are experimental.rNFr)r) rrrrcheck_hostname CERT_NONErrrr) rr,rr5r8ryrzr|r{rrhandlerrDrDrEtls_auth_handlers   r)gatewayjobrR grouping_keyrrr[cCstd||||||dS)aNPush metrics to the given pushgateway. `gateway` the url for your push gateway. Either of the form 'http://pushgateway.local', or 'pushgateway.local'. Scheme defaults to 'http' if none is provided `job` is the job label to be attached to all pushed metrics `registry` is an instance of CollectorRegistry `grouping_key` please see the pushgateway documentation for details. Defaults to None `timeout` is how long push will attempt to connect before giving up. Defaults to 30s, can be set to None for no timeout. `handler` is an optional function which can be provided to perform requests to the 'gateway'. Defaults to None, in which case an http or https request will be carried out by a default handler. If not None, the argument must be a function which accepts the following arguments: url, method, timeout, headers, and content May be used to implement additional functionality not supported by the built-in default handler (such as SSL client certicates, and HTTP authentication mechanisms). 'url' is the URL for the request, the 'gateway' argument described earlier will form the basis of this URL. 'method' is the HTTP method which should be used when carrying out the request. 'timeout' requests not successfully completed after this many seconds should be aborted. If timeout is None, then the handler should not set a timeout. 'headers' is a list of ("header-name","header-value") tuples which must be passed to the pushgateway in the form of HTTP request headers. The function should raise an exception (e.g. IOError) on failure. 'content' is the data which should be used to form the HTTP Message Body. This overwrites all metrics with the same job and grouping_key. This uses the PUT HTTP method.r3N _use_gatewayrrrRrrrrDrDrEr&s.r&cCstd||||||dS)a"PushAdd metrics to the given pushgateway. `gateway` the url for your push gateway. Either of the form 'http://pushgateway.local', or 'pushgateway.local'. Scheme defaults to 'http' if none is provided `job` is the job label to be attached to all pushed metrics `registry` is an instance of CollectorRegistry `grouping_key` please see the pushgateway documentation for details. Defaults to None `timeout` is how long push will attempt to connect before giving up. Defaults to 30s, can be set to None for no timeout. `handler` is an optional function which can be provided to perform requests to the 'gateway'. Defaults to None, in which case an http or https request will be carried out by a default handler. See the 'prometheus_client.push_to_gateway' documentation for implementation requirements. This replaces metrics with the same name, job and grouping_key. This uses the POST HTTP method.r2NrrrDrDrEr'sr')rrrrrr[cCstd||d|||dS)aDelete metrics from the given pushgateway. `gateway` the url for your push gateway. Either of the form 'http://pushgateway.local', or 'pushgateway.local'. Scheme defaults to 'http' if none is provided `job` is the job label to be attached to all pushed metrics `grouping_key` please see the pushgateway documentation for details. Defaults to None `timeout` is how long delete will attempt to connect before giving up. Defaults to 30s, can be set to None for no timeout. `handler` is an optional function which can be provided to perform requests to the 'gateway'. Defaults to None, in which case an http or https request will be carried out by a default handler. See the 'prometheus_client.push_to_gateway' documentation for implementation requirements. This deletes metrics with the given job and grouping_key. This uses the DELETE HTTP method.DELETENr)rrrrrrDrDrEr 3sr )r,rrrRrrrr[c Cst|}|jr|jdkr"d|}|d}dj|ftd|}d} |dkrb|dkrZt}t|} |dkrni}|dd d t| D7}||||d t fg| d dS) N)httphttpszhttp:///z{}/metrics/{}/{}rr]rr\css*|]"\}}djtt|t|VqdS)z/{}/{}N)rf_escape_grouping_keyrrrDrDrE isz_use_gateway..rKr) rschemerstriprfr rr!rrrr) r,rrrRrrrZ gateway_urlrr8rDrDrErPs,     rcCsJ|dkr|ddfSd|kr:|dt|ddfS|t|fSdS)Nr\z@base64=r r)rurlsafe_b64encoderdecoder)rrrDrDrEr ss  r rc Cs\tttjtj>}tjdkr,|dn |dd|diW5QRSQRXdS)z>Grouping key with instance set to the IP Address of this host.darwin)z10.255.255.255r) localhostrinstancerN)rrmAF_INET SOCK_DGRAMsysplatformconnect getsockname)rrDrDrEr"~s    r")r#)NNF)NN)Ur contextlibrrLZ http.serverrrrm socketserverrrrrtypingrrrrr r r r urllib.errorr urllib.parserrrurllib.requestrrrrrrZwsgiref.simple_serverrrrrrrRrrutilsr__all__rr+rZboolr$rcrirxrrrrPROTOCOL_TLS_SERVERrr)r(bytesr!rNrOr%r*rrkrrrrPROTOCOL_TLS_CLIENTrr&r'r rr r"Zasgir#rDrDrDrEs@   (    7 + >" &     # & 5 "  #