B
    U                 @   s   d Z ddlZddlZddlZyFyddlmZ W n  ek
rN   ddlmZ Y nX ddl	m
Z
 dZW n ek
rz   dZY nX G dd deZG d	d
 d
eZdddZdS )a9  
    werkzeug.contrib.profiler
    ~~~~~~~~~~~~~~~~~~~~~~~~~

    This module provides a simple WSGI profiler middleware for finding
    bottlenecks in web application.  It uses the :mod:`profile` or
    :mod:`cProfile` module to do the profiling and writes the stats to the
    stream provided (defaults to stderr).

    Example usage::

        from werkzeug.contrib.profiler import ProfilerMiddleware
        app = ProfilerMiddleware(app)

    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
    N)Profile)StatsTFc               @   s    e Zd ZdZdd Zdd ZdS )MergeStreamzAn object that redirects `write` calls to multiple streams.
    Use this to log to both `sys.stdout` and a file::

        f = open('profiler.log', 'w')
        stream = MergeStream(sys.stdout, f)
        profiler = ProfilerMiddleware(app, stream)
    c             G   s   |st d|| _d S )Nz!at least one stream must be given)	TypeErrorstreams)selfr    r   8lib/python3.7/site-packages/werkzeug/contrib/profiler.py__init__+   s    zMergeStream.__init__c             C   s   x| j D ]}|| qW d S )N)r   write)r   datastreamr   r   r	   r   0   s    zMergeStream.writeN)__name__
__module____qualname____doc__r
   r   r   r   r   r	   r   !   s   r   c               @   s"   e Zd ZdZd	ddZdd ZdS )
ProfilerMiddlewarea  Simple profiler middleware.  Wraps a WSGI application and profiles
    a request.  This intentionally buffers the response so that timings are
    more exact.

    By giving the `profile_dir` argument, pstat.Stats files are saved to that
    directory, one file per request. Without it, a summary is printed to
    `stream` instead.

    For the exact meaning of `sort_by` and `restrictions` consult the
    :mod:`profile` documentation.

    .. versionadded:: 0.9
       Added support for `restrictions` and `profile_dir`.

    :param app: the WSGI application to profile.
    :param stream: the stream for the profiled stats.  defaults to stderr.
    :param sort_by: a tuple of columns to sort the result by.
    :param restrictions: a tuple of profiling strictions, not used if dumping
                         to `profile_dir`.
    :param profile_dir: directory name to save pstat files
    Ntimecallsr   c             C   s4   t std|| _|ptj| _|| _|| _|| _d S )NzHthe profiler is not available because profile or pstat is not installed.)		availableRuntimeError_appsysstdout_stream_sort_by_restrictions_profile_dir)r   appr   sort_byrestrictionsZprofile_dirr   r   r	   r
   M   s    zProfilerMiddleware.__init__c       
   	      s  g dfdd	  fdd}t  }t }|| d}t | }jd k	rtjjdd dd		d	d
pd|d t f }|
| nTt|jd}	|	jj  jd jdd  |	jj  jd |gS )Nc                s   | ||  j S )N)append)ZstatusZheadersexc_info)response_bodystart_responser   r	   catching_start_response[   s    z<ProfilerMiddleware.__call__.<locals>.catching_start_responsec                 s,     } |  t| dr(|   d S )Nclose)r   extendhasattrr'   )Zappiter)r&   environr$   r   r   r	   runapp_   s    

z+ProfilerMiddleware.__call__.<locals>.runapp    z%s.%s.%06dms.%d.profZREQUEST_METHODZ	PATH_INFO/.rootg     @@)r   zP--------------------------------------------------------------------------------z

PATH: %r
zR--------------------------------------------------------------------------------

)N)r   r   Zruncalljoinr   ospathgetstripreplaceZ
dump_statsr   r   Z
sort_statsr   r   Zprint_statsr   )
r   r*   r%   r+   pstartZbodyelapsedZprof_filenameZstatsr   )r&   r*   r$   r   r%   r	   __call__X   s0    




zProfilerMiddleware.__call__)Nr   r   N)r   r   r   r   r
   r9   r   r   r   r	   r   5   s    

r   	localhost     r   r   r   c       	         s(   d|fd|f||f fdd	}|S )zReturn a new callback for :mod:`werkzeug.script` that starts a local
    server with the profiler enabled.

    ::

        from werkzeug.contrib import profiler
        action_profile = profiler.make_action(make_app)
    hr6   c                s4   ddl m} t  }|| ||dd|| dS )zStart a new development server.r   )
run_simpleFN)Zwerkzeug.servingr?   r   )hostnameportthreaded	processesr?   r   )app_factoryr!   r    r   r   r	   action   s    zmake_action.<locals>.actionr   )	rD   r@   rA   rB   rC   r   r    r!   rE   r   )rD   r!   r    r   r	   make_action   s    rF   )r:   r;   Fr<   Nr=   r   )r   r   r   os.pathr1   ZcProfiler   ImportErrorZprofileZpstatsr   r   objectr   r   rF   r   r   r   r	   <module>   s"   
M  