= raidgrep(1) :doctype: manpage :man source: raidgrep :man manual: raidgrep manpage :toc: :homepage: https://gitlab.com/dunj3/raidgrep == NAME raidgrep - A search tool for Guild Wars 2/arcdps log files. == SYNOPSIS *raidgrep* ['-OPTION' ['...']] ['--' ['-PREDICATE' ['...']]] == DESCRIPTION raidgrep is a CLI search tool to search through .evtc log files generated by arcdps (a Guild Wars 2 addon). raidgrep was inspired by other search tools - namely +ripgrep+ and +find+ - but has support for reading and parsing the binary files produced by arcdps and applying Guild Wars 2 specific filters. == OPTIONS The following options have to be given before any filters are given on the command line: *--debug*:: Print more debugging information to stderr. *-l*, *--files-with-matches*:: Only show the name of matching files. *--guilds*:: Load guild information from the API. + + Loading guild information requires network access and slows down the program considerably, so this is disabled by default. *--no-color*:: Disable colored output. *--repl*:: Run the REPL. *-V*, *--version*:: Prints version information. *-d* 'path', *--dir* 'path':: Path to the folder with logs [default: .] *-c* 'file', *--check* 'file':: Check the given log file only. + + If this option is given, the given file will be checked against the given filter. This does not produce any output, will will set the exit code accordingly (see section 'EXIT STATUS'). *-s* 'sorting', *--sort* 'sorting':: Sort the output according to the given fields. Valid fields are 'boss', 'date', 'cm' and 'outcome'. Fields can be comma-separated, then later fields are used to break ties. Fields can be prefixed by ~ to indicate sorting in the opposite direction. + + Note that using this option will cause raidgrep to buffer all results until the search has finished, which means that no output will happen until every file has been searched. It can also lead to a higher memory consumption, based on how many logs are matched. Therefore, it is advised that you do not use this option unless needed. + == PREDICATES The following predicates can be used after the options. Note that they should be preceeded by a +--+ on the command line, to signal the parser to switch from parsing options to parsing predicates. === Predicate Combinators 'A' [*and*] 'B':: Match the log only if both 'A' and 'B' are matching. The *and* is optional, predicates written after each other are implicitely joined with *and*. 'A' *or* 'B':: Match the log if 'A' or 'B' are matching. *not* 'PREDICATE':: Match the log only if the given predicate does not match. *(* 'PREDICATE' *)*:: Parenthesis can be used to group predicates to enforce the correct operator ordering. === Log Predicates Those predicates can be used as-is in the filter: *-success*:: Include logs that are successful. *-wipe*:: Include logs that are failed. *-outcome* 'OUTCOMES':: Include logs with the given outcomes. Outcomes are 'success', 'wipe', or a comma-separated combination thereof. *-weekday* 'WEEKDAYS':: Include logs made on the given weekdays. Weekdays are given either fully or as a 3-letter-abbreviation and can be combined by commas. *-before* 'DATE':: Include logs made before the given date. Date can be either in "year-month-day" or "year-month-day hour:minute:second" format. *-after* 'DATE':: Include logs made after the given date. See *-before* for valid date formats. *-log-before* 'DATE', *-log-after* 'DATE':: Same as *-before* and *-after*, but does not use file name heuristics to filter the date. + + This can fix wrong results in case you renamed files, but it comes at the cost of worse runtime performance. You should always use *-before*/*-after* when possible! *-boss* 'BOSSES':: Include logs from the given bosses. See below for a list of valid boss names. Names can also be comma separated. *-cm*:: Include logs that were done with the Challenge Mote enabled. *-player* 'REGEX':: Include logs in which at least one player's account or character name matches the given regex. + + Note that you have to quote the regex if it contains spaces or other special characters. *all(player:* 'PREDICATES' *)*:: Include logs in which all players match the given player predicates. See below for a list of player predicates. *any(player:* 'PREDICATES' *)*:: Include logs in which any player matches the given player predicates. See below for a list of player predicates. === Comparative Predicates Some predicates work by comparing a log value against a given constant (or other computed value). Comparisons are done using the operators '<', '\<=', '=', '>' and '>=' - in the list below, the placeholder '<>' will be used in place of one of the comparison operators. *-time* '<>' 'DATE':: Include logs whose timestamp is in relation to the given date. This is a generalized version of the *-before* and *-after* predicates and accepts the same date formats. *-duration* '<>' 'DURATION':: Include logs whose duration is in relation to the given duration. The duration is given as minutes and/or seconds: "42m", "42m 42s" or "42s". *count(player)* '<>' 'COUNT':: Include logs whose player count is in relation to the given count. This counts all players in the log. *count(player:* 'PREDICATES' *)* '<>' 'COUNT':: Include logs whose player count is in relation to the given count, only counting players that are matching the given player predicates. See below for a list of player predicates. === Player Predicates The following predicates have to be wrapped in either a *any(player: ...)*, *all(player: ...)* or *count(player: ...)* construct to be accepted. *-character* 'REGEX':: Matches the player if the character name matches the given regular expression. *-account* 'REGEX':: Matches the player if the account name matches the given regular expression. *-name* 'REGEX':: Shorthand that matches if the character or the account name match the given regular expression. *-class* 'CLASSES':: Match the player if they have one of the given classes. Note that a core class won't match its elite specializations, so _Guardian_ won't match _Dragonhunter_. + + Names can be comma separated, in which case the player must have any of the listed classes. === Boss Names Bosses can be referred to by their official name, although if that name contains spaces it must be enclosed in quotes, and it's cumbersome to write. Therefore, raidgrep also accepts a lot of shorthands that are established in the community. The following list is an inexhaustive list of all accepted boss names, with one name per boss given: * *Wing 1*: vg, gorseval, sabetha * *Wing 2*: slothasor, matthias * *Wing 3*: kc, xera * *Wing 4*: cairn, mo, samarog, deimos * *Wing 5*: desmina, dhuum * *Wing 6*: ca, largos, qadim * *Wing 7*: adina, sabir, qadimp * *100 CM*: skorvald, artsariiv, arkk * *99 CM*: mama, siax, ensolyss * *Strike Missions*: icebrood, fraenir, kodans, boneskinner, whisper === Regular Expressions raidgrep uses Rust's +regex+ library for regular expression support. A full syntax reference can be found at https://docs.rs/regex/#syntax. A (very) short primer is given here: *foo*:: Match foo literally. *foo|bar*:: Match either foo or bar. *.*:: Match any character. *^*:: Match the beginning of the string. *$*:: Match the end of the string. === A Note About Quoting raidgrep uses its own parser to split and parse the given predicates. However, when calling raidgrep from the command line, the shell also applies some splitting. raidgrep tries to reconstruct the given predicates as good as possible, but it does not always work. This means that sometimes, predicates as described here may not work correctly when used in the CLI argument. To circumvent this, there are multiple options: * Use the raidgrep REPL, which is not subject to your shell's splitting. * Pass the filter as a single big argument, which is usually achieved by enclosing it in quotes and escaping any quotes in the filter. Most use cases should work without much adaption. If there is a case that looks like it should work but doesn't, feel free to report it as a bug (see below). == REPL If given the *--repl* option, raidgrep will not start searching for logs and instead enter a read-eval-print-loop. You can give it a predicate, it will print the results and ask for the next predicate. Any options given in this mode will apply to the whole REPL session. For example, if started with *-l*, all REPL evaluations will only print the file names of the matching files. == EXIT STATUS raidgrep will exit with status 0 (success) if at least one matching log was found, with status 1 if no logs were found and status 2 if there was an error. If used with the REPL mode, raidgrep will always exit with status 0. == EXAMPLES The following are examples of predicates as they might be entered in the REPL. They can also be used on the command line, but proper escaping might have to be applied (depending on your shell): +-success -player Godric+:: Find any logs that were successful and had a player called "Godric" in them. +-wipe (-player Godric or -player Emma)+:: Find any logs that were unsuccesful and had either a player called "Godric" or a player called "Emma" in them. +-after 2020-01-01 any(player: -character Xenia)+:: Find any logs after the 1st of January 2020 where a player had a character name matching "Xenia". The following examples are raidgrep invocations that show how predicates can be supplied as arguments to raidgrep: `raidgrep -- -success -player Godric`:: Same as above. Special quoting is not necessary, as raidgrep can figure out what the user meant. `raidgrep -- -player "Godric Gobbledygook"`:: Find any logs with a player called "Godric Gobbledygook". Raidgrep can figure out how the quotes were meant to be, even though the shell stripped them away. `raidgrep -- 'all(player: -character "o{2}")'`:: In this example, the whole command line is wrapped in single quotes, to prevent the shell from splitting it apart. This should work for most predicates. == FILES * '$XDG_CACHE_HOME/raidgrep': Temporary data. * '$XDG_CONFIG_HOME/raidgrep/history': REPL history. Note that 'XDG_CACHE_HOME' defaults to '\~/.cache' if unset, and 'XDG_CONFIG_HOME' defaults to '~/.config'. == BUGS Bugs and other issues are tracked in the Gitlab repository at https://gitlab.com/dunj3/raidgrep/-/issues. If you want to report a bug, you can either * Open an issue in the aforementioned issue tracker * Write an email to mailto:raidgrep@kingdread.de[] * Contact me through Guild Wars 2: +Dunje.4863+ When reporting a bug, please include as much information as you can beforehand - that includes the version of raidgrep that you are using, your operating system and (if possible) the log file itself that raidgrep fails on. == COPYRIGHT This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . == RESOURCES * Source repository: https://gitlab.com/dunj3/raidgrep/ * Binary releases: https://kingdread.de/raidgrep/ * arcdps addon for Guild Wars 2: https://www.deltaconnected.com/arcdps/ == AUTHOR *raidgrep* was written by Daniel Schadt.