1919log .add (sys .stderr , format = fmt )
2020
2121
22- def parse_logs (logs : List [str ]) -> Dict [str , Any ]:
22+ def parse_rasterio_io_logs (logs : List [str ]) -> Dict [str , Any ]:
2323 """Parse Rasterio and CURL logs."""
2424 # HEAD
2525 head_requests = len ([line for line in logs if "CURL_INFO_HEADER_OUT: HEAD" in line ])
@@ -53,25 +53,67 @@ def parse_logs(logs: List[str]) -> Dict[str, Any]:
5353 }
5454
5555
56+ def parse_vsifile_io_logs (logs : List [str ]) -> Dict [str , Any ]:
57+ """Parse VSIFILE IO logs."""
58+ # HEAD
59+ head_requests = len (
60+ [line for line in logs if "VSIFILE_INFO_HEADER_OUT: HEAD" in line ]
61+ )
62+ head_summary = {
63+ "count" : head_requests ,
64+ }
65+
66+ # GET
67+ all_get_requests = len (
68+ [line for line in logs if "VSIFILE_INFO_HEADER_OUT: GET" in line ]
69+ )
70+
71+ get_requests = [line for line in logs if "VSIFILE: Downloading: " in line ]
72+
73+ get_values_str = []
74+ for get in get_requests :
75+ get_values_str .extend (get .split ("VSIFILE: Downloading: " )[1 ].split (", " ))
76+
77+ get_values = [list (map (int , r .split ("-" ))) for r in get_values_str ]
78+ data_transfer = sum ([j - i + 1 for i , j in get_values ])
79+
80+ get_summary = {
81+ "count" : all_get_requests ,
82+ "bytes" : data_transfer ,
83+ "ranges" : get_values_str ,
84+ }
85+
86+ warp_kernel = [line .split (" " )[- 2 :] for line in logs if "GDALWarpKernel" in line ]
87+
88+ return {
89+ "HEAD" : head_summary ,
90+ "GET" : get_summary ,
91+ "WarpKernels" : warp_kernel ,
92+ }
93+
94+
5695def profile (
5796 kernels : bool = False ,
5897 add_to_return : bool = False ,
5998 quiet : bool = False ,
6099 raw : bool = False ,
61100 cprofile : bool = False ,
62101 config : Optional [Dict ] = None ,
102+ io = "rasterio" ,
63103):
64104 """Profiling."""
105+ if io not in ["rasterio" , "vsifile" ]:
106+ raise ValueError (f"Unsupported { io } IO backend" )
65107
66108 def wrapper (func : Callable ):
67109 """Wrap a function."""
68110
69111 def wrapped_f (* args , ** kwargs ):
70112 """Wrapped function."""
71- rio_stream = StringIO ()
72- logger = logging .getLogger ("rasterio" )
113+ io_stream = StringIO ()
114+ logger = logging .getLogger (io )
73115 logger .setLevel (logging .DEBUG )
74- handler = logging .StreamHandler (rio_stream )
116+ handler = logging .StreamHandler (io_stream )
75117 logger .addHandler (handler )
76118
77119 gdal_config = config or {}
@@ -88,10 +130,15 @@ def wrapped_f(*args, **kwargs):
88130 logger .removeHandler (handler )
89131 handler .close ()
90132
91- logs = rio_stream .getvalue ().splitlines ()
133+ logs = io_stream .getvalue ().splitlines ()
92134 profile_lines = [p for p in profile_stream .getvalue ().splitlines () if p ]
93135
94- results = parse_logs (logs )
136+ results = {}
137+ if io == "vsifile" :
138+ results .update (parse_vsifile_io_logs (logs ))
139+ else :
140+ results .update (parse_rasterio_io_logs (logs ))
141+
95142 results ["Timing" ] = t .elapsed
96143
97144 if cprofile :
0 commit comments