1<!-- 2© 2019 and later: Unicode, Inc. and others. 3License & terms of use: http://www.unicode.org/copyright.html 4--> 5 6Resource and Data Tracing 7========================= 8 9When building an [ICU data filter specification](buildtool.md), it is useful to 10see what resources are being used by your application so that you can select 11those resources and discard the others. This guide describes how to use 12*utrace.h* to inspect resource access in real time in ICU4C. 13 14**Note:** This feature is only available in ICU4C at this time. If you are 15interested in ICU4J, please see 16[ICU-20656](https://unicode-org.atlassian.net/browse/ICU-20656). 17 18## Quick Start 19 20First, you *must* have a copy of ICU4C configured with tracing enabled. 21 22 $ ./runConfigureICU Linux --enable-tracing 23 24The following program prints resource and data usages to standard out: 25 26```cpp 27#include "unicode/brkiter.h" 28#include "unicode/errorcode.h" 29#include "unicode/localpointer.h" 30#include "unicode/utrace.h" 31 32#include <iostream> 33 34static void U_CALLCONV traceData( 35 const void *context, 36 int32_t fnNumber, 37 int32_t level, 38 const char *fmt, 39 va_list args) { 40 char buf[1000]; 41 const char *fnName; 42 43 fnName = utrace_functionName(fnNumber); 44 utrace_vformat(buf, sizeof(buf), 0, fmt, args); 45 std::cout << fnName << " " << buf << std::endl; 46} 47 48int main() { 49 icu::ErrorCode status; 50 51 const void* context = nullptr; 52 utrace_setFunctions(context, nullptr, nullptr, traceData); 53 utrace_setLevel(UTRACE_VERBOSE); 54 55 // Create a new BreakIterator 56 icu::LocalPointer<icu::BreakIterator> brkitr( 57 icu::BreakIterator::createWordInstance("zh-CN", status)); 58} 59``` 60 61The following output is produced from this program: 62 63 res-open icudt64l-brkitr/zh_CN.res 64 res-open icudt64l-brkitr/zh.res 65 res-open icudt64l-brkitr/root.res 66 bundle-open icudt64l-brkitr/zh.res 67 resc (get) icudt64l-brkitr/zh.res @ /boundaries 68 resc (get) icudt64l-brkitr/root.res @ /boundaries/word 69 resc (string) icudt64l-brkitr/root.res @ /boundaries/word 70 file-open icudt64l-brkitr/word.brk 71 72What this means: 73 741. The BreakIterator constructor opened three resource files in the locale 75 fallback chain for zh_CN. The actual bundle was opened for zh. 762. One string was read from that resource bundle: the one at the resource path 77 "/boundaries/word" in brkitr/root.res. 783. In addition, the binary data file brkitr/word.brk was opened. 79 80Based on that information, you can make a more informed decision when writing 81resource filter rules for this simple program. 82 83## Data Tracing API 84 85The `traceData` function shown above takes five arguments. The following two 86are most important for data tracing: 87 88- `fnNumber` indicates what type of data access this is. 89- `args` contains the details on which resources were accessed. 90 91**Important:** When reading from `args`, the strings are valid only within the 92scope of your `traceData` function. You should make copies of the strings if 93you intend to save them for further processing. 94 95### UTRACE_UDATA_RESOURCE 96 97UTRACE_UDATA_RESOURCE is used to indicate that a value inside of a resource 98bundle was read by ICU code. 99 100When `fnNumber` is `UTRACE_UDATA_RESOURCE`, there are three C-style strings in 101`args`: 102 1031. Data type; not usually relevant for the purpose of resource filtering. 1042. The internal path of the resource file from which the value was read. 1053. The path to the value within that resource file. 106 107To read each of these into different variables, you can write the code, 108 109```cpp 110const char* dataType = va_arg(args, const char*); 111const char* filePath = va_arg(args, const char*); 112const char* resPath = va_arg(args, const char*); 113``` 114 115As stated above, you should copy the strings if you intend to save them. The 116pointers will not be valid after the tracing function returns. 117 118### UTRACE_UDATA_BUNDLE 119 120UTRACE_UDATA_BUNDLE is used to indicate that a resource bundle was opened by 121ICU code. 122 123For the purposes of making your ICU data filter, the specific resource paths 124provided by UTRACE_UDATA_RESOURCE are more precise and useful. 125 126### UTRACE_UDATA_DATA_FILE 127 128UTRACE_UDATA_DATA_FILE is used to indicate that a non-resource-bundle binary 129data file was opened by ICU code. Such files are used for break iteration, 130conversion, confusables, and a handful of other ICU services. 131 132### UTRACE_UDATA_RES_FILE 133 134UTRACE_UDATA_RES_FILE is used to indicate that a binary resource bundle file 135was opened by ICU code. This can be helpful to debug locale fallbacks. This 136differs from UTRACE_UDATA_BUNDLE because the resource *file* is typically 137opened only once per application runtime. 138 139For the purposes of making your ICU data filter, the specific resource paths 140provided by UTRACE_UDATA_RESOURCE are more precise and useful. 141