This is my Go implementation of an "all-singing / all-dancing" utility to pretty-print logfiles containing FIX Protocol messages while experimenting with a compact native Go command-line shape and trying to incorporate SonarQube Code Quality metrics.
I have written utilities like this in past in Java, Python, C, C++, go and even in Bash/Awk!! Rust remains my favourite, but this Go version is the small native implementation that helped shape the later Rust and Java versions.
☕ If you found this project useful, consider buying me a coffee or dropping a comment — it keeps the caffeine and ideas flowing! 😄
fixdecoder is a FIX-aware logfile prettifier and dictionary explorer. It reads stdin or one or more log files, detects FIX messages in each line, prints the original line, and follows it with a colourised tag breakdown using embedded FIX dictionaries or a supplied QuickFIX XML dictionary. For lookup work, --info, --message, --component, and --tag inspect the selected FIX version without decoding a log stream.
This Go implementation is intentionally simpler than the Rust and Java repos. It focuses on fast native builds, embedded dictionary lookup, command-line dictionary browsing, and straightforward logfile prettification.
make build
# Stream and prettify stdin
cat fixlog.txt | scripts/fixdecoder
# Decode one or more files
scripts/fixdecoder logs/fix.log logs/fix2.log
# Browse dictionary definitions
scripts/fixdecoder --fix=44 --message=D --verbose --column --header --trailerYou can run fixdecoder anywhere you can run a Go binary. The standard build embeds FIX dictionaries for FIX 4.0 through FIX 5.0 SP2 plus FIXT 1.1, and --xml can point at an alternative QuickFIX XML file for custom dictionaries.
From a source checkout, scripts/fixdecoder runs the local bin/fixdecoder produced by make build; set FIXDECODER_BIN=/path/to/fixdecoder to override discovery.
The text below is generated by running this implementation's fixdecoder --help.
fixdecoder v1.0.0 (branch:main, commit:fb6b474) [go:go1.26.4]
git clone https://github.com/stephenlclarke/fixdecoder_go.git
Usage: fixdecoder [--xml=FILE] [--fix=VERSION] [--info] [--message[=MSG]]
[--component[=NAME]] [--tag[=TAG]] [--column] [--verbose] [--header]
[--trailer] [-h|--help] [-v|--version] [file1.log file2.log ...]
Pretty-print FIX log messages and inspect FIX dictionaries.
Arguments:
file1.log file2.log ...
FIX log files, or stdin when omitted.
Options:
--xml=FILE Path to alternative FIX XML file.
--fix=VERSION FIX version to use.
--info Show XML schema summary.
--message[=MSG] Message name or MsgType; omit the value to list all messages.
--component[=NAME] Component to display; omit the value to list all components.
--tag[=TAG] Tag number to display details for; omit the value to list all tags.
--column Display enum values in columns.
--verbose Show full message structure with enums.
--header Include the Header block.
--trailer Include the Trailer block.
-h, --help Show this help message and exit.
-v, --version Print version information and exit.
Command line option examples:
FIX dictionary lookup
Query FIX dictionary contents by FIX Message Name or MsgType:
fixdecoder [[--xml=FILE] [--fix=44]]
--message[=NAME|MSGTYPE]
[--column] [--verbose] [--header] [--trailer]
$ fixdecoder --message=NewOrderSingle --verbose --column --header --trailer
$ fixdecoder --message=D --verbose --column --header --trailer
Query FIX dictionary contents by FIX Tag number:
fixdecoder [[--xml=FILE] [--fix=44]]
--tag[=TAG]
[--column] [--verbose]
$ fixdecoder --tag=44 --verbose --column
Query FIX dictionary contents by FIX Component Name:
fixdecoder [[--xml=FILE] [--fix=44]]
--component[=NAME]
[--column] [--verbose]
$ fixdecoder --component=Instrument --verbose --column
Show summary information about the selected FIX dictionary:
fixdecoder [[--xml=FILE] [--fix=44]]
--info
$ fixdecoder --info
Prettify FIX log files:
fixdecoder [--xml=FILE] [--fix=VERSION]
[--column] [--verbose] [--header] [--trailer]
[file1.log file2.log ...]
Force the decoding of a FIX log to use the FIX 4.4 dictionary.
$ fixdecoder --fix=44 trades.log
Decode stdin using a custom FIX XML dictionary:
$ cat logs/fix.log | fixdecoder --xml=resources/FIX44.xml --fix=44
Show the full help or version details:
$ fixdecoder --help
$ fixdecoder --version
- Dictionaries:
--xml,--fix,--info,--message,--component,--tag - Output/layout:
--column,--verbose,--header,--trailer - Input: one or more log files, or stdin when no file is supplied
This snapshot is generated by make regen-readme by running this implementation's binary and reflects the options and dictionary surface currently available in this repository.
- Supported long options:
--column,--component,--fix,--header,--help,--info,--message,--tag,--trailer,--verbose,--version,--xml - Sample message discovered from the dictionary:
NewOrderSingle (D) - Sample component discovered from the dictionary:
PreAllocGrp - Sample repeating group tag discovered from the dictionary:
NoPartyIDs (453)
$ scripts/fixdecoder --fix=44 --message=D --column
Message: NewOrderSingle (D)
Message: Body
11: ClOrdID (STRING) - (Y)
526: SecondaryClOrdID (STRING)
583: ClOrdLinkID (STRING)
Component: Parties
453: NoPartyIDs (NUMINGROUP)
448: PartyID (STRING)
447: PartyIDSource (CHAR)
452: PartyRole (INT)
Component: PtysSubGrp
802: NoPartySubIDs (NUMINGROUP)
523: PartySubID (STRING)
803: PartySubIDType (INT)
229: TradeOriginationDate (LOCALMKTDATE)
75: TradeDate (LOCALMKTDATE)
1: Account (STRING)
660: AcctIDSource (INT)
...$ scripts/fixdecoder --fix=44 --component=PreAllocGrp --column
Component: PreAllocGrp
78: NoAllocs (NUMINGROUP)
79: AllocAccount (STRING)
661: AllocAcctIDSource (INT)
736: AllocSettlCurrency (CURRENCY)
467: IndividualAllocID (STRING)
Component: NestedParties
539: NoNestedPartyIDs (NUMINGROUP)
524: NestedPartyID (STRING)
525: NestedPartyIDSource (CHAR)
538: NestedPartyRole (INT)
Component: NstdPtysSubGrp
804: NoNestedPartySubIDs (NUMINGROUP)
545: NestedPartySubID (STRING)
805: NestedPartySubIDType (INT)
80: AllocQty (QTY)$ scripts/fixdecoder --fix=44 --tag=453 --verbose --column
453: NoPartyIDs (NUMINGROUP)These examples are generated by make regen-readme using the Go command-line application.
$ printf '<FIX log>' | scripts/fixdecoder
Processing: (stdin)
8=FIX.4.4|9=22|35=0|49=BUY1|56=SELL1|10=168|
8 (BeginString): FIX.4.4
9 (BodyLength): 22
35 (MsgType): 0 (Heartbeat)
49 (SenderCompID): BUY1
56 (TargetCompID): SELL1
10 (CheckSum): 168$ scripts/fixdecoder --info
Available FIX Dictionaries: 40,41,42,43,44,50,50SP1,50SP2,T11
Current Schema:
FIX Version: 4.4
Service Pack: 0
Messages: 93
Components: 106
Fields: 912$ scripts/fixdecoder --fix=44 --message=D --column
Message: NewOrderSingle (D)
Message: Body
11: ClOrdID (STRING) - (Y)
526: SecondaryClOrdID (STRING)
583: ClOrdLinkID (STRING)
Component: Parties
453: NoPartyIDs (NUMINGROUP)
448: PartyID (STRING)
447: PartyIDSource (CHAR)
452: PartyRole (INT)
Component: PtysSubGrp
802: NoPartySubIDs (NUMINGROUP)
523: PartySubID (STRING)
803: PartySubIDType (INT)
229: TradeOriginationDate (LOCALMKTDATE)
75: TradeDate (LOCALMKTDATE)
1: Account (STRING)
660: AcctIDSource (INT)
581: AccountType (INT)
589: DayBookingInst (CHAR)
590: BookingUnit (CHAR)
591: PreallocMethod (CHAR)
70: AllocID (STRING)
Component: PreAllocGrp
78: NoAllocs (NUMINGROUP)
79: AllocAccount (STRING)
...$ scripts/fixdecoder --fix=44 --component=PreAllocGrp --column
Component: PreAllocGrp
78: NoAllocs (NUMINGROUP)
79: AllocAccount (STRING)
661: AllocAcctIDSource (INT)
736: AllocSettlCurrency (CURRENCY)
467: IndividualAllocID (STRING)
Component: NestedParties
539: NoNestedPartyIDs (NUMINGROUP)
524: NestedPartyID (STRING)
525: NestedPartyIDSource (CHAR)
538: NestedPartyRole (INT)
Component: NstdPtysSubGrp
804: NoNestedPartySubIDs (NUMINGROUP)
545: NestedPartySubID (STRING)
805: NestedPartySubIDType (INT)
80: AllocQty (QTY)$ scripts/fixdecoder --fix=44 --tag=453 --verbose --column
453: NoPartyIDs (NUMINGROUP)Build it from source. This requires bash and a recent Go toolchain.
❯ bash --version
GNU bash, version 5.3.15(1)-release (aarch64-apple-darwin25.4.0)
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>❯ go version
go version go1.26.4 darwin/arm64Clone the git repo.
❯ git clone git@github.com:stephenlclarke/fixdecoder_go.git
Cloning into 'fixdecoder_go'...
...
❯ cd fixdecoder_goThen build it. Local builds compile the binary and run the test suites used by CI.
❯ make build unit-test integration-test
>> Setting up environment
>> Running go mod tidy in all modules
>> Building the application
>> Running unit tests
>> Running integration testsBuild all release-style fixdecoder binaries.
❯ make build-all
>> Building for OS: darwin, ARCH: arm64
>> Building for OS: linux, ARCH: arm64
>> Building for OS: linux, ARCH: amd64
>> Building for OS: windows, ARCH: amd64Run it (from the release build) and check the version details:
❯ ./bin/fixdecoder --version
fixdecoder v1.0.0 (branch:main, commit:fb6b474) [go:go1.26.4]Run the same build through the source-checkout wrapper:
❯ scripts/fixdecoder --version
fixdecoder v1.0.0 (branch:main, commit:fb6b474) [go:go1.26.4]The local workflow uses Go and the repo's ci.sh wrapper.
make build
make unit-test
make integration-test
make scan
go test ./... -coverThe FIX dictionary Go source is regenerated from the XML resources with:
./resources/generate_fix_go.shThe public traffic badge is generated from GitHub Insights by .github/workflows/traffic-badge.yml. Configure a repository secret named TRAFFIC_TOKEN that can call the repository traffic API; for a fine-grained personal access token, grant Repository permissions > Administration: read. The scheduled workflow publishes only the aggregate 14-day unique visitor and view counts to .badges/traffic.json.
- fixdecoder_rs is the Rust version and remains my favourite.
- fixdecoder_java is the Java version with object-oriented internals, Maven, JaCoCo coverage, and Java CI/CD.
Project source is released under the GNU Affero General Public License v3.0 only (AGPL-3.0-only). Maintained source files carry SPDX headers:
SPDX-License-Identifier: AGPL-3.0-only
SPDX-FileCopyrightText: 2026 Steve Clarke <stephenlclarke@mac.com> - https://xyzzy.tools
The embedded FIX dictionary packages are generated from QuickFIX FIX XML specifications. Those QuickFIX materials remain under the BSD 2-Clause “Simplified” License; see NOTICE.md for the retained attribution text and compatibility note.


