1983afe33SPhil Shafer 2983afe33SPhil ShaferFAQs 3983afe33SPhil Shafer==== 4983afe33SPhil Shafer 5983afe33SPhil ShaferThis section contains the set of questions that users typically ask, 6983afe33SPhil Shaferalong with answers that might be helpful. 7983afe33SPhil Shafer 8983afe33SPhil ShaferGeneral 9983afe33SPhil Shafer------- 10983afe33SPhil Shafer 11983afe33SPhil ShaferCan you share the history of libxo? 12983afe33SPhil Shafer~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13983afe33SPhil Shafer 14983afe33SPhil ShaferIn 2001, we added an XML API to the JUNOS operating system, which is 15983afe33SPhil Shaferbuilt on top of FreeBSD_. Eventually this API became standardized as 16983afe33SPhil Shaferthe NETCONF API (:RFC:`6241`). As part of this effort, we modified many 17983afe33SPhil ShaferFreeBSD utilities to emit XML, typically via a "-X" switch. The 18983afe33SPhil Shaferresults were mixed. The cost of maintaining this code, updating it, 19983afe33SPhil Shaferand carrying it were non-trivial, and contributed to our expense (and 20983afe33SPhil Shaferthe associated delay) with upgrading the version of FreeBSD on which 21983afe33SPhil Shafereach release of JUNOS is based. 22983afe33SPhil Shafer 23983afe33SPhil Shafer.. _FreeBSD: https://www.freebsd.org 24983afe33SPhil Shafer 25983afe33SPhil ShaferA recent (2014) effort within JUNOS aims at removing our modifications 26983afe33SPhil Shaferto the underlying FreeBSD code as a means of reducing the expense and 27983afe33SPhil Shaferdelay in tracking HEAD. JUNOS is structured to have system components 28983afe33SPhil Shafergenerate XML that is rendered by the CLI (think: login shell) into 29983afe33SPhil Shaferhuman-readable text. This allows the API to use the same plumbing as 30983afe33SPhil Shaferthe CLI, and ensures that all components emit XML, and that it is 31983afe33SPhil Shaferemitted with knowledge of the consumer of that XML, yielding an API 32983afe33SPhil Shaferthat have no incremental cost or feature delay. 33983afe33SPhil Shafer 34983afe33SPhil Shaferlibxo is an effort to mix the best aspects of the JUNOS strategy into 35983afe33SPhil ShaferFreeBSD in a seemless way, allowing commands to make printf-like 36983afe33SPhil Shaferoutput calls with a single code path. 37983afe33SPhil Shafer 38983afe33SPhil ShaferDid the complex semantics of format strings evolve over time? 39983afe33SPhil Shafer~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40983afe33SPhil Shafer 41983afe33SPhil ShaferThe history is both long and short: libxo's functionality is based 42983afe33SPhil Shaferon what JUNOS does in a data modeling language called ODL (output 43983afe33SPhil Shaferdefinition language). In JUNOS, all subcomponents generate XML, 44983afe33SPhil Shaferwhich is feed to the CLI, where data from the ODL files tell is 45983afe33SPhil Shaferhow to render that XML into text. ODL might had a set of tags 46983afe33SPhil Shaferlike:: 47983afe33SPhil Shafer 48983afe33SPhil Shafer tag docsis-state { 49983afe33SPhil Shafer help "State of the DOCSIS interface"; 50983afe33SPhil Shafer type string; 51983afe33SPhil Shafer } 52983afe33SPhil Shafer 53983afe33SPhil Shafer tag docsis-mode { 54983afe33SPhil Shafer help "DOCSIS mode (2.0/3.0) of the DOCSIS interface"; 55983afe33SPhil Shafer type string; 56983afe33SPhil Shafer } 57983afe33SPhil Shafer 58983afe33SPhil Shafer tag docsis-upstream-speed { 59983afe33SPhil Shafer help "Operational upstream speed of the interface"; 60983afe33SPhil Shafer type string; 61983afe33SPhil Shafer } 62983afe33SPhil Shafer 63983afe33SPhil Shafer tag downstream-scanning { 64983afe33SPhil Shafer help "Result of scanning in downstream direction"; 65983afe33SPhil Shafer type string; 66983afe33SPhil Shafer } 67983afe33SPhil Shafer 68983afe33SPhil Shafer tag ranging { 69983afe33SPhil Shafer help "Result of ranging action"; 70983afe33SPhil Shafer type string; 71983afe33SPhil Shafer } 72983afe33SPhil Shafer 73983afe33SPhil Shafer tag signal-to-noise-ratio { 74983afe33SPhil Shafer help "Signal to noise ratio for all channels"; 75983afe33SPhil Shafer type string; 76983afe33SPhil Shafer } 77983afe33SPhil Shafer 78983afe33SPhil Shafer tag power { 79983afe33SPhil Shafer help "Operational power of the signal on all channels"; 80983afe33SPhil Shafer type string; 81983afe33SPhil Shafer } 82983afe33SPhil Shafer 83983afe33SPhil Shafer format docsis-status-format { 84983afe33SPhil Shafer picture " 85983afe33SPhil Shafer State : @, Mode: @, Upstream speed: @ 86983afe33SPhil Shafer Downstream scanning: @, Ranging: @ 87983afe33SPhil Shafer Signal to noise ratio: @ 88983afe33SPhil Shafer Power: @ 89983afe33SPhil Shafer "; 90983afe33SPhil Shafer line { 91983afe33SPhil Shafer field docsis-state; 92983afe33SPhil Shafer field docsis-mode; 93983afe33SPhil Shafer field docsis-upstream-speed; 94983afe33SPhil Shafer field downstream-scanning; 95983afe33SPhil Shafer field ranging; 96983afe33SPhil Shafer field signal-to-noise-ratio; 97983afe33SPhil Shafer field power; 98983afe33SPhil Shafer } 99983afe33SPhil Shafer } 100983afe33SPhil Shafer 101983afe33SPhil ShaferThese tag definitions are compiled into field definitions 102983afe33SPhil Shaferthat are triggered when matching XML elements are seen. ODL 103983afe33SPhil Shaferalso supports other means of defining output. 104983afe33SPhil Shafer 105983afe33SPhil ShaferThe roles and modifiers describe these details. 106983afe33SPhil Shafer 107983afe33SPhil ShaferIn moving these ideas to bsd, two things had to happen: the 108983afe33SPhil Shaferformatting had to happen at the source since BSD won't have 109983afe33SPhil Shafera JUNOS-like CLI to do the rendering, and we can't depend on 110983afe33SPhil Shaferexternal data models like ODL, which was seen as too hard a 111983afe33SPhil Shafersell to the BSD community. 112983afe33SPhil Shafer 113983afe33SPhil ShaferThe results were that the xo_emit strings are used to encode the 114983afe33SPhil Shaferroles, modifiers, names, and formats. They are dense and a bit 115983afe33SPhil Shafercryptic, but not so unlike printf format strings that developers will 116983afe33SPhil Shaferbe lost. 117983afe33SPhil Shafer 118983afe33SPhil Shaferlibxo is a new implementation of these ideas and is distinct from 119983afe33SPhil Shaferthe previous implementation in JUNOS. 120983afe33SPhil Shafer 121983afe33SPhil Shafer.. index:: XOF_UNDERSCORES 122983afe33SPhil Shafer 123983afe33SPhil Shafer.. _good-field-names: 124983afe33SPhil Shafer 125983afe33SPhil ShaferWhat makes a good field name? 126983afe33SPhil Shafer~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127983afe33SPhil Shafer 128983afe33SPhil ShaferTo make useful, consistent field names, follow these guidelines: 129983afe33SPhil Shafer 130983afe33SPhil ShaferUse lower case, even for TLAs 131983afe33SPhil Shafer Lower case is more civilized. Even TLAs should be lower case 132983afe33SPhil Shafer to avoid scenarios where the differences between "XPath" and 133983afe33SPhil Shafer "Xpath" drive your users crazy. Using "xpath" is simpler and better. 134983afe33SPhil Shafer 135983afe33SPhil ShaferUse hyphens, not underscores 136983afe33SPhil Shafer Use of hyphens is traditional in XML, and the XOF_UNDERSCORES 137983afe33SPhil Shafer flag can be used to generate underscores in JSON, if desired. 138983afe33SPhil Shafer But the raw field name should use hyphens. 139983afe33SPhil Shafer 140983afe33SPhil ShaferUse full words 141983afe33SPhil Shafer Don't abbreviate especially when the abbreviation is not obvious or 142983afe33SPhil Shafer not widely used. Use "data-size", not "dsz" or "dsize". Use 143983afe33SPhil Shafer "interface" instead of "ifname", "if-name", "iface", "if", or "intf". 144983afe33SPhil Shafer 145983afe33SPhil ShaferUse <verb>-<units> 146983afe33SPhil Shafer Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in 147983afe33SPhil Shafer making consistent, useful names, avoiding the situation where one app 148983afe33SPhil Shafer uses "sent-packet" and another "packets-sent" and another 149983afe33SPhil Shafer "packets-we-have-sent". The <units> can be dropped when it is 150983afe33SPhil Shafer obvious, as can obvious words in the classification. 151983afe33SPhil Shafer Use "receive-after-window-packets" instead of 152983afe33SPhil Shafer "received-packets-of-data-after-window". 153983afe33SPhil Shafer 154983afe33SPhil ShaferReuse existing field names 155983afe33SPhil Shafer Nothing's worse than writing expressions like:: 156983afe33SPhil Shafer 157983afe33SPhil Shafer if ($src1/process[pid == $pid]/name == 158983afe33SPhil Shafer $src2/proc-table/proc-list 159983afe33SPhil Shafer /prc-entry[prcss-id == $pid]/proc-name) { 160983afe33SPhil Shafer ... 161983afe33SPhil Shafer } 162983afe33SPhil Shafer 163983afe33SPhil Shafer Find someone else who is expressing similar data and follow their 164983afe33SPhil Shafer fields and hierarchy. Remember the quote is not "Consistency is the 165983afe33SPhil Shafer hobgoblin of little minds", but "A *foolish* consistency is the 166983afe33SPhil Shafer hobgoblin of little minds". Consistency rocks! 167983afe33SPhil Shafer 168983afe33SPhil ShaferUse containment as scoping 169983afe33SPhil Shafer In the previous example, all the names are prefixed with "proc-", 170983afe33SPhil Shafer which is redundant given that they are nested under the process table. 171983afe33SPhil Shafer 172983afe33SPhil ShaferThink about your users 173983afe33SPhil Shafer Have empathy for your users, choosing clear and useful fields that 174983afe33SPhil Shafer contain clear and useful data. You may need to augment the display 175983afe33SPhil Shafer content with xo_attr() calls (:ref:`xo_attr`) or "{e:}" 176983afe33SPhil Shafer fields (:ref:`encoding-modifier`) to make the data useful. 177983afe33SPhil Shafer 178983afe33SPhil ShaferDon't use an arbitrary number postfix 179983afe33SPhil Shafer What does "errors2" mean? No one will know. "errors-after-restart" 180983afe33SPhil Shafer would be a better choice. Think of your users, and think of the 181983afe33SPhil Shafer future. If you make "errors2", the next guy will happily make 182983afe33SPhil Shafer "errors3" and before you know it, someone will be asking what's the 183983afe33SPhil Shafer difference between errors37 and errors63. 184983afe33SPhil Shafer 185983afe33SPhil ShaferBe consistent, uniform, unsurprising, and predictable 186983afe33SPhil Shafer Think of your field vocabulary as an API. You want it useful, 187983afe33SPhil Shafer expressive, meaningful, direct, and obvious. You want the client 188983afe33SPhil Shafer application's programmer to move between without the need to 189983afe33SPhil Shafer understand a variety of opinions on how fields are named. They 190983afe33SPhil Shafer should see the system as a single cohesive whole, not a sack of 191983afe33SPhil Shafer cats. 192983afe33SPhil Shafer 193983afe33SPhil ShaferField names constitute the means by which client programmers interact 194983afe33SPhil Shaferwith our system. By choosing wise names now, you are making their 195983afe33SPhil Shaferlives better. 196983afe33SPhil Shafer 197983afe33SPhil ShaferAfter using `xolint` to find errors in your field descriptors, use 198983afe33SPhil Shafer"`xolint -V`" to spell check your field names and to help you detect 199983afe33SPhil Shaferdifferent names for the same data. "dropped-short" and 200983afe33SPhil Shafer"dropped-too-short" are both reasonable names, but using them both 201983afe33SPhil Shaferwill lead users to ask the difference between the two fields. If 202983afe33SPhil Shaferthere is no difference, use only one of the field names. If there is 203983afe33SPhil Shafera difference, change the names to make that difference more obvious. 204983afe33SPhil Shafer 205983afe33SPhil ShaferWhat does this message mean? 20676afb20cSPhil Shafer~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 207983afe33SPhil Shafer 208*34b867caSPhil Shafer.. toctree:: 209*34b867caSPhil Shafer :maxdepth: 2 210*34b867caSPhil Shafer 211*34b867caSPhil Shafer xolint-errors.rst 212