[{"data":1,"prerenderedAt":1657},["ShallowReactive",2],{"navigation":3,"\u002Fconnector-development\u002Fguides\u002Flogging":775,"\u002Fconnector-development\u002Fguides\u002Flogging-surround":1652},[4,80,155,385,449,551,588,667],{"title":5,"path":6,"stem":7,"children":8,"page":42},"Get Started","\u002Fget-started","01.get-started",[9,13,17,43,47],{"title":10,"path":11,"stem":12},"Welcome to UniteLabs","\u002Fget-started\u002Fwelcome","01.get-started\u002F00.welcome",{"title":14,"path":15,"stem":16},"How it works","\u002Fget-started\u002Fhow-it-works","01.get-started\u002F01.how-it-works",{"title":18,"path":19,"stem":20,"children":21,"page":42},"Use Cases","\u002Fget-started\u002Fuse-cases","01.get-started\u002F02.use-cases",[22,26,30,34,38],{"title":23,"path":24,"stem":25},"Instrument Control","\u002Fget-started\u002Fuse-cases\u002Flow-level-instrument-control","01.get-started\u002F02.use-cases\u002F10.low-level-instrument-control",{"title":27,"path":28,"stem":29},"Multi-device Control","\u002Fget-started\u002Fuse-cases\u002Fmulti-device-control","01.get-started\u002F02.use-cases\u002F20.multi-device-control",{"title":31,"path":32,"stem":33},"Workflow Orchestration","\u002Fget-started\u002Fuse-cases\u002Fworkflow-orchestration","01.get-started\u002F02.use-cases\u002F30.workflow-orchestration",{"title":35,"path":36,"stem":37},"Custom Apps and LIMS Integration","\u002Fget-started\u002Fuse-cases\u002Fcustom-apps-lims","01.get-started\u002F02.use-cases\u002F40.custom-apps-lims",{"title":39,"path":40,"stem":41},"Scale and Fleet Management","\u002Fget-started\u002Fuse-cases\u002Fscale-and-fleet","01.get-started\u002F02.use-cases\u002F50.scale-and-fleet",false,{"title":44,"path":45,"stem":46},"Lab as Code","\u002Fget-started\u002Fwhy-code","01.get-started\u002F03.why-code",{"title":48,"path":49,"stem":50,"children":51,"page":42},"Setup","\u002Fget-started\u002Fsetup","01.get-started\u002F20.setup",[52,56,60,64,68,72,76],{"title":53,"path":54,"stem":55},"GroundControl","\u002Fget-started\u002Fsetup\u002Fgroundcontrol","01.get-started\u002F20.setup\u002F10.groundcontrol",{"title":57,"path":58,"stem":59},"Network requirements","\u002Fget-started\u002Fsetup\u002Fnetwork-requirements","01.get-started\u002F20.setup\u002F20.network-requirements",{"title":61,"path":62,"stem":63},"Multi-device Networking","\u002Fget-started\u002Fsetup\u002Fmultiple-devices","01.get-started\u002F20.setup\u002F30.multiple-devices",{"title":65,"path":66,"stem":67},"Connect to Platform","\u002Fget-started\u002Fsetup\u002Fconnect-to-platform","01.get-started\u002F20.setup\u002F40.connect-to-platform",{"title":69,"path":70,"stem":71},"Headless install","\u002Fget-started\u002Fsetup\u002Fheadless-install","01.get-started\u002F20.setup\u002F50.headless-install",{"title":73,"path":74,"stem":75},"Raspberry Pi","\u002Fget-started\u002Fsetup\u002Fraspberry-pi","01.get-started\u002F20.setup\u002F55.raspberry-pi",{"title":77,"path":78,"stem":79},"Installation","\u002Fget-started\u002Fsetup\u002Fsdk-installation","01.get-started\u002F20.setup\u002F60.sdk-installation",{"title":81,"path":82,"stem":83,"children":84,"page":42},"Integrate","\u002Fintegrate","02.integrate",[85,89,93,118,139],{"title":86,"path":87,"stem":88},"What is a connector?","\u002Fintegrate\u002Fwhat-is-a-connector","02.integrate\u002F00.what-is-a-connector",{"title":90,"path":91,"stem":92},"Calling a Connector","\u002Fintegrate\u002Fcontrol-with-code","02.integrate\u002F05.control-with-code",{"title":94,"path":95,"stem":96,"children":97,"page":42},"Concepts","\u002Fintegrate\u002Fconcepts","02.integrate\u002F10.concepts",[98,102,106,110,114],{"title":99,"path":100,"stem":101},"Connector","\u002Fintegrate\u002Fconcepts\u002Fconnector","02.integrate\u002F10.concepts\u002F10.connector",{"title":103,"path":104,"stem":105},"Module","\u002Fintegrate\u002Fconcepts\u002Fmodule","02.integrate\u002F10.concepts\u002F20.module",{"title":107,"path":108,"stem":109},"Action","\u002Fintegrate\u002Fconcepts\u002Faction","02.integrate\u002F10.concepts\u002F30.action",{"title":111,"path":112,"stem":113},"Subscription","\u002Fintegrate\u002Fconcepts\u002Fsubscription","02.integrate\u002F10.concepts\u002F40.subscription",{"title":115,"path":116,"stem":117},"Device","\u002Fintegrate\u002Fconcepts\u002Fdevice","02.integrate\u002F10.concepts\u002F50.device",{"title":119,"path":120,"stem":121,"children":122,"page":42},"Connect a device","\u002Fintegrate\u002Fconnect-a-device","02.integrate\u002F20.connect-a-device",[123,127,131,135],{"title":124,"path":125,"stem":126},"Via GroundControl","\u002Fintegrate\u002Fconnect-a-device\u002Fvia-groundcontrol","02.integrate\u002F20.connect-a-device\u002F10.via-groundcontrol",{"title":128,"path":129,"stem":130},"With an executable","\u002Fintegrate\u002Fconnect-a-device\u002Fwith-an-executable","02.integrate\u002F20.connect-a-device\u002F20.with-an-executable",{"title":132,"path":133,"stem":134},"From source","\u002Fintegrate\u002Fconnect-a-device\u002Ffrom-source","02.integrate\u002F20.connect-a-device\u002F30.from-source",{"title":136,"path":137,"stem":138},"Build your own","\u002Fintegrate\u002Fconnect-a-device\u002Fbuild-yourself","02.integrate\u002F20.connect-a-device\u002F40.build-yourself",{"title":140,"path":141,"stem":142,"children":143,"page":42},"Use a connector","\u002Fintegrate\u002Fuse-a-connector","02.integrate\u002F30.use-a-connector",[144,147,151],{"title":53,"path":145,"stem":146},"\u002Fintegrate\u002Fuse-a-connector\u002Fgroundcontrol","02.integrate\u002F30.use-a-connector\u002F10.groundcontrol",{"title":148,"path":149,"stem":150},"Platform","\u002Fintegrate\u002Fuse-a-connector\u002Fplatform","02.integrate\u002F30.use-a-connector\u002F20.platform",{"title":152,"path":153,"stem":154},"UniteLabs SDK & REST API","\u002Fintegrate\u002Fuse-a-connector\u002Fpython","02.integrate\u002F30.use-a-connector\u002F30.python",{"title":156,"path":157,"stem":158,"children":159,"page":42},"Operate","\u002Foperate","03.operate",[160,163,167,207,280],{"title":156,"path":161,"stem":162},"\u002Foperate\u002Foverview","03.operate\u002F00.overview",{"title":164,"path":165,"stem":166},"Your First Protocol","\u002Foperate\u002Fyour-first-protocol","03.operate\u002F05.your-first-protocol",{"title":94,"path":168,"stem":169,"children":170,"page":42},"\u002Foperate\u002Fconcepts","03.operate\u002F10.concepts",[171,175,179,183,187,191,195,199,203],{"title":172,"path":173,"stem":174},"Liquid Handling","\u002Foperate\u002Fconcepts\u002Fliquid-handling","03.operate\u002F10.concepts\u002F10.liquid-handling",{"title":176,"path":177,"stem":178},"Modules","\u002Foperate\u002Fconcepts\u002Fmodules","03.operate\u002F10.concepts\u002F20.modules",{"title":180,"path":181,"stem":182},"Deck","\u002Foperate\u002Fconcepts\u002Fdeck","03.operate\u002F10.concepts\u002F30.deck",{"title":184,"path":185,"stem":186},"Labware","\u002Foperate\u002Fconcepts\u002Flabware","03.operate\u002F10.concepts\u002F40.labware",{"title":188,"path":189,"stem":190},"Liquids","\u002Foperate\u002Fconcepts\u002Fliquids","03.operate\u002F10.concepts\u002F50.liquids",{"title":192,"path":193,"stem":194},"Liquid Classes","\u002Foperate\u002Fconcepts\u002Fliquid-classes","03.operate\u002F10.concepts\u002F60.liquid-classes",{"title":196,"path":197,"stem":198},"Tips and Tip Tracking","\u002Foperate\u002Fconcepts\u002Ftips","03.operate\u002F10.concepts\u002F70.tips",{"title":200,"path":201,"stem":202},"Simulation","\u002Foperate\u002Fconcepts\u002Fsimulation","03.operate\u002F10.concepts\u002F80.simulation",{"title":204,"path":205,"stem":206},"Error Handling","\u002Foperate\u002Fconcepts\u002Ferror-handling","03.operate\u002F10.concepts\u002F90.error-handling",{"title":208,"path":209,"stem":210,"children":211,"page":42},"Guides","\u002Foperate\u002Fguides","03.operate\u002F20.guides",[212,241,253,277],{"title":184,"path":213,"stem":214,"children":215},"\u002Foperate\u002Fguides\u002Flabware","03.operate\u002F20.guides\u002F10.labware\u002Findex",[216,217,221,225,229,233,237],{"title":184,"path":213,"stem":214},{"title":218,"path":219,"stem":220},"Standard Labware","\u002Foperate\u002Fguides\u002Flabware\u002Fstandard-labware","03.operate\u002F20.guides\u002F10.labware\u002F05.standard-labware",{"title":222,"path":223,"stem":224},"Plates","\u002Foperate\u002Fguides\u002Flabware\u002Fplates","03.operate\u002F20.guides\u002F10.labware\u002F10.plates",{"title":226,"path":227,"stem":228},"Tips and Tip Racks","\u002Foperate\u002Fguides\u002Flabware\u002Ftips-and-racks","03.operate\u002F20.guides\u002F10.labware\u002F20.tips-and-racks",{"title":230,"path":231,"stem":232},"Tubes and Tube Racks","\u002Foperate\u002Fguides\u002Flabware\u002Ftubes-and-tube-racks","03.operate\u002F20.guides\u002F10.labware\u002F30.tubes-and-tube-racks",{"title":234,"path":235,"stem":236},"Troughs","\u002Foperate\u002Fguides\u002Flabware\u002Ftroughs","03.operate\u002F20.guides\u002F10.labware\u002F35.troughs",{"title":238,"path":239,"stem":240},"Carriers and Adapters","\u002Foperate\u002Fguides\u002Flabware\u002Fcarriers-and-adapters","03.operate\u002F20.guides\u002F10.labware\u002F40.carriers-and-adapters",{"title":180,"path":242,"stem":243,"children":244,"page":42},"\u002Foperate\u002Fguides\u002Fdeck","03.operate\u002F20.guides\u002F20.deck",[245,249],{"title":246,"path":247,"stem":248},"Building a Deck","\u002Foperate\u002Fguides\u002Fdeck\u002Fbuilding-a-deck","03.operate\u002F20.guides\u002F20.deck\u002F10.building-a-deck",{"title":250,"path":251,"stem":252},"Save\u002FLoad a Deck","\u002Foperate\u002Fguides\u002Fdeck\u002Fsave-load-deck","03.operate\u002F20.guides\u002F20.deck\u002F20.save-load-deck",{"title":254,"path":255,"stem":256,"children":257,"page":42},"Pipetting","\u002Foperate\u002Fguides\u002Fpipetting","03.operate\u002F20.guides\u002F30.pipetting",[258,262,266,270,273],{"title":259,"path":260,"stem":261},"Basic Pipetting","\u002Foperate\u002Fguides\u002Fpipetting\u002Fbasic-pipetting","03.operate\u002F20.guides\u002F30.pipetting\u002F10.basic-pipetting",{"title":263,"path":264,"stem":265},"Advanced Pipetting","\u002Foperate\u002Fguides\u002Fpipetting\u002Fadvanced-pipetting","03.operate\u002F20.guides\u002F30.pipetting\u002F20.advanced-pipetting",{"title":267,"path":268,"stem":269},"Tip Handling","\u002Foperate\u002Fguides\u002Fpipetting\u002Ftip-handling","03.operate\u002F20.guides\u002F30.pipetting\u002F30.tip-handling",{"title":192,"path":271,"stem":272},"\u002Foperate\u002Fguides\u002Fpipetting\u002Fliquid-classes","03.operate\u002F20.guides\u002F30.pipetting\u002F40.liquid-classes",{"title":274,"path":275,"stem":276},"Labware Transport","\u002Foperate\u002Fguides\u002Fpipetting\u002Flabware-transport","03.operate\u002F20.guides\u002F30.pipetting\u002F50.labware-transport",{"title":200,"path":278,"stem":279},"\u002Foperate\u002Fguides\u002Fsimulation","03.operate\u002F20.guides\u002F40.simulation",{"title":281,"path":282,"stem":283,"children":284,"page":42},"Liquid Handler Guides","\u002Foperate\u002Fdevices","03.operate\u002F30.devices",[285,326,351,368],{"title":286,"path":287,"stem":288,"children":289,"page":42},"Hamilton STAR","\u002Foperate\u002Fdevices\u002Fhamilton-star","03.operate\u002F30.devices\u002F10.hamilton-star",[290,294,298,302,306,310,314,318,322],{"title":291,"path":292,"stem":293},"Positioning & Movement","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fpositioning","03.operate\u002F30.devices\u002F10.hamilton-star\u002F10.positioning",{"title":295,"path":296,"stem":297},"Gripper Module","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fcore-gripper","03.operate\u002F30.devices\u002F10.hamilton-star\u002F20.core-gripper",{"title":299,"path":300,"stem":301},"iSWAP Module","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fiswap","03.operate\u002F30.devices\u002F10.hamilton-star\u002F30.iswap",{"title":303,"path":304,"stem":305},"Using TADM","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Ftadm","03.operate\u002F30.devices\u002F10.hamilton-star\u002F40.tadm",{"title":307,"path":308,"stem":309},"Autoload Module","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fautoload","03.operate\u002F30.devices\u002F10.hamilton-star\u002F50.autoload",{"title":311,"path":312,"stem":313},"Waste Block","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fwaste-block","03.operate\u002F30.devices\u002F10.hamilton-star\u002F60.waste-block",{"title":315,"path":316,"stem":317},"Complex Mixing","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fcomplex-mixing","03.operate\u002F30.devices\u002F10.hamilton-star\u002F66.complex-mixing",{"title":319,"path":320,"stem":321},"Teaching Gripper Paddle Positions","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fgripper-positions","03.operate\u002F30.devices\u002F10.hamilton-star\u002F70.gripper-positions",{"title":323,"path":324,"stem":325},"Training a Custom Deck Position With the iSWAP","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fcustom-deck-position","03.operate\u002F30.devices\u002F10.hamilton-star\u002F75.custom-deck-position",{"title":327,"path":328,"stem":329,"children":330,"page":42},"Hamilton Vantage","\u002Foperate\u002Fdevices\u002Fhamilton-vantage","03.operate\u002F30.devices\u002F20.hamilton-vantage",[331,335,339,343,347],{"title":332,"path":333,"stem":334},"Waste Configuration","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fwaste-configuration","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F05.waste-configuration",{"title":336,"path":337,"stem":338},"Covers and Lights","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fcovers-and-lights","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F10.covers-and-lights",{"title":340,"path":341,"stem":342},"IDL Module","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fidl","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F20.idl",{"title":344,"path":345,"stem":346},"IPG Module","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fipg","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F30.ipg",{"title":348,"path":349,"stem":350},"XL Pipettes","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fxl-channels","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F40.xl-channels",{"title":352,"path":353,"stem":354,"children":355,"page":42},"Agilent Bravo","\u002Foperate\u002Fdevices\u002Fagilent-bravo","03.operate\u002F30.devices\u002F30.agilent-bravo",[356,359,362,365],{"title":267,"path":357,"stem":358},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Ftip-handling","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F10.tip-handling",{"title":259,"path":360,"stem":361},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Fbasic-pipetting","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F20.basic-pipetting",{"title":192,"path":363,"stem":364},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Fliquid-classes","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F25.liquid-classes",{"title":295,"path":366,"stem":367},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Fusing-the-gripper","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F30.using-the-gripper",{"title":369,"path":370,"stem":371,"children":372,"page":42},"Tecan FluentControl","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol",[373,377,381],{"title":374,"path":375,"stem":376},"Connect & Run a Method","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol\u002Fconnect-and-run","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol\u002F10.connect-and-run",{"title":378,"path":379,"stem":380},"Sending XML Commands","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol\u002Fsending-xml-commands","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol\u002F20.sending-xml-commands",{"title":382,"path":383,"stem":384},"Full Workflow Example","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol\u002Ffull-workflow-example","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol\u002F30.full-workflow-example",{"title":386,"path":387,"stem":388,"children":389,"page":42},"Device Guides","\u002Fdevice-guides","06.device-guides",[390,393,406,423,436],{"title":386,"path":391,"stem":392},"\u002Fdevice-guides\u002Foverview","06.device-guides\u002F00.overview",{"title":394,"path":395,"stem":396,"children":397,"page":42},"Incubation","\u002Fdevice-guides\u002Fincubation","06.device-guides\u002F20.incubation",[398,402],{"title":399,"path":400,"stem":401},"Inheco ODTC","\u002Fdevice-guides\u002Fincubation\u002Finheco-odtc","06.device-guides\u002F20.incubation\u002F10.inheco-odtc",{"title":403,"path":404,"stem":405},"Inheco SCILA","\u002Fdevice-guides\u002Fincubation\u002Finheco-scila","06.device-guides\u002F20.incubation\u002F20.inheco-scila",{"title":407,"path":408,"stem":409,"children":410,"page":42},"Heater-Shakers","\u002Fdevice-guides\u002Fheater-shakers","06.device-guides\u002F30.heater-shakers",[411,415,419],{"title":412,"path":413,"stem":414},"Inheco Thermoshake","\u002Fdevice-guides\u002Fheater-shakers\u002Finheco-thermoshake","06.device-guides\u002F30.heater-shakers\u002F10.inheco-thermoshake",{"title":416,"path":417,"stem":418},"QInstruments Bioshake","\u002Fdevice-guides\u002Fheater-shakers\u002Fqinstruments-bioshake","06.device-guides\u002F30.heater-shakers\u002F20.qinstruments-bioshake",{"title":420,"path":421,"stem":422},"QInstruments ColdPlate","\u002Fdevice-guides\u002Fheater-shakers\u002Fqinstruments-coldplate","06.device-guides\u002F30.heater-shakers\u002F30.qinstruments-coldplate",{"title":424,"path":425,"stem":426,"children":427,"page":42},"Readers","\u002Fdevice-guides\u002Freaders","06.device-guides\u002F40.readers",[428,432],{"title":429,"path":430,"stem":431},"Biotek Gen5","\u002Fdevice-guides\u002Freaders\u002Fbiotek-gen5","06.device-guides\u002F40.readers\u002F10.biotek-gen5",{"title":433,"path":434,"stem":435},"Biotek Synergy H1","\u002Fdevice-guides\u002Freaders\u002Fbiotek-synergy-h1","06.device-guides\u002F40.readers\u002F20.biotek-synergy-H1",{"title":437,"path":438,"stem":439,"children":440,"page":42},"Tilt & Turn","\u002Fdevice-guides\u002Ftilt-and-turn","06.device-guides\u002F50.tilt-and-turn",[441,445],{"title":442,"path":443,"stem":444},"TurnStation","\u002Fdevice-guides\u002Ftilt-and-turn\u002Fqinstruments-turnstation","06.device-guides\u002F50.tilt-and-turn\u002F10.qinstruments-turnstation",{"title":446,"path":447,"stem":448},"TiltStation","\u002Fdevice-guides\u002Ftilt-and-turn\u002Fqinstruments-tiltstation","06.device-guides\u002F50.tilt-and-turn\u002F20.qinstruments-tiltstation",{"title":450,"path":451,"stem":452,"children":453,"page":42},"Automate","\u002Fautomate","07.automate",[454,458,462,466,515],{"title":455,"path":456,"stem":457},"What is a workflow?","\u002Fautomate\u002Fwhat-is-a-workflow","07.automate\u002F00.what-is-a-workflow",{"title":459,"path":460,"stem":461},"Workflow template","\u002Fautomate\u002Fworkflow-template","07.automate\u002F05.workflow-template",{"title":463,"path":464,"stem":465},"Your First Workflow","\u002Fautomate\u002Fyour-first-workflow","07.automate\u002F08.your-first-workflow",{"title":94,"pages":467,"path":477,"stem":478,"children":479,"page":42},[468,469,470,471,472,473,474,475,476],"workflow","phase","step","runs","input","artifacts","logs","human-in-the-loop","error-handling","\u002Fautomate\u002Fconcepts","07.automate\u002F10.concepts",[480,484,488,492,496,500,504,508,512],{"title":481,"path":482,"stem":483},"Workflow","\u002Fautomate\u002Fconcepts\u002Fworkflow","07.automate\u002F10.concepts\u002F10.workflow",{"title":485,"path":486,"stem":487},"Phase","\u002Fautomate\u002Fconcepts\u002Fphase","07.automate\u002F10.concepts\u002F20.phase",{"title":489,"path":490,"stem":491},"Step","\u002Fautomate\u002Fconcepts\u002Fstep","07.automate\u002F10.concepts\u002F30.step",{"title":493,"path":494,"stem":495},"Runs","\u002Fautomate\u002Fconcepts\u002Fruns","07.automate\u002F10.concepts\u002F40.runs",{"title":497,"path":498,"stem":499},"Input","\u002Fautomate\u002Fconcepts\u002Finput","07.automate\u002F10.concepts\u002F50.input",{"title":501,"path":502,"stem":503},"Artifacts","\u002Fautomate\u002Fconcepts\u002Fartifacts","07.automate\u002F10.concepts\u002F60.artifacts",{"title":505,"path":506,"stem":507},"Logs","\u002Fautomate\u002Fconcepts\u002Flogs","07.automate\u002F10.concepts\u002F70.logs",{"title":509,"path":510,"stem":511},"Human in the Loop","\u002Fautomate\u002Fconcepts\u002Fhuman-in-the-loop","07.automate\u002F10.concepts\u002F80.human-in-the-loop",{"title":204,"path":513,"stem":514},"\u002Fautomate\u002Fconcepts\u002Ferror-handling","07.automate\u002F10.concepts\u002F90.error-handling",{"title":208,"path":516,"stem":517,"children":518,"page":42},"\u002Fautomate\u002Fguides","07.automate\u002F25.guides",[519,523,527,531,535,539,543,547],{"title":520,"path":521,"stem":522},"Deploy a workflow","\u002Fautomate\u002Fguides\u002Fdeploy-a-workflow","07.automate\u002F25.guides\u002F30.deploy-a-workflow",{"title":524,"path":525,"stem":526},"Run a workflow","\u002Fautomate\u002Fguides\u002Frun-a-workflow","07.automate\u002F25.guides\u002F35.run-a-workflow",{"title":528,"path":529,"stem":530},"CI\u002FCD for workflows","\u002Fautomate\u002Fguides\u002Fcicd-for-workflows","07.automate\u002F25.guides\u002F40.cicd-for-workflows",{"title":532,"path":533,"stem":534},"HITL basics","\u002Fautomate\u002Fguides\u002Fbasic-hitl","07.automate\u002F25.guides\u002F50.basic-hitl",{"title":536,"path":537,"stem":538},"Typed operator inputs","\u002Fautomate\u002Fguides\u002Ftyped-operator-inputs","07.automate\u002F25.guides\u002F55.typed-operator-inputs",{"title":540,"path":541,"stem":542},"Error recovery","\u002Fautomate\u002Fguides\u002Fbasic-error-handling","07.automate\u002F25.guides\u002F60.basic-error-handling",{"title":544,"path":545,"stem":546},"Advanced error handling","\u002Fautomate\u002Fguides\u002Fadvanced-error-handling","07.automate\u002F25.guides\u002F70.advanced-error-handling",{"title":548,"path":549,"stem":550},"Workflows REST API","\u002Fautomate\u002Fguides\u002Fworkflows-api","07.automate\u002F25.guides\u002F80.workflows-api",{"title":552,"path":553,"stem":554,"children":555,"page":42},"Observe","\u002Fobserve","08.observe",[556,560,576],{"title":557,"path":558,"stem":559},"Overview","\u002Fobserve\u002Foverview","08.observe\u002F10.overview",{"title":94,"path":561,"stem":562,"children":563,"page":42},"\u002Fobserve\u002Fconcepts","08.observe\u002F20.concepts",[564,568,572],{"title":565,"path":566,"stem":567},"Object Storage","\u002Fobserve\u002Fconcepts\u002Fstorage","08.observe\u002F20.concepts\u002F10.storage",{"title":569,"path":570,"stem":571},"Secrets","\u002Fobserve\u002Fconcepts\u002Fsecrets","08.observe\u002F20.concepts\u002F20.secrets",{"title":573,"path":574,"stem":575},"Data sources","\u002Fobserve\u002Fconcepts\u002Fdata-sources","08.observe\u002F20.concepts\u002F30.data-sources",{"title":208,"path":577,"stem":578,"children":579,"page":42},"\u002Fobserve\u002Fguides","08.observe\u002F30.guides",[580,584],{"title":581,"path":582,"stem":583},"File System Connector","\u002Fobserve\u002Fguides\u002Ffilesystem-connector","08.observe\u002F30.guides\u002F10.filesystem-connector",{"title":585,"path":586,"stem":587},"Building an ETL","\u002Fobserve\u002Fguides\u002Fbuilding-an-etl","08.observe\u002F30.guides\u002F20.building-an-etl",{"title":589,"path":590,"stem":591,"children":592,"page":42},"Technical Reference","\u002Ftechnical-reference","10.technical-reference",[593,597,601,613,624,635,645,656],{"title":594,"path":595,"stem":596},"Introduction","\u002Ftechnical-reference\u002Fplatform-blueprint","10.technical-reference\u002F00.platform-blueprint",{"title":598,"path":599,"stem":600},"REST API","\u002Ftechnical-reference\u002Frest-api","10.technical-reference\u002F01.rest-api",{"title":53,"path":602,"stem":603,"children":604,"page":42},"\u002Ftechnical-reference\u002Fgroundcontrol","10.technical-reference\u002F10.groundcontrol",[605,609],{"title":606,"path":607,"stem":608},"Install & Setup","\u002Ftechnical-reference\u002Fgroundcontrol\u002Finstall","10.technical-reference\u002F10.groundcontrol\u002F10.install",{"title":610,"path":611,"stem":612},"Changelog","\u002Ftechnical-reference\u002Fgroundcontrol\u002Fchangelog","10.technical-reference\u002F10.groundcontrol\u002F20.changelog",{"title":614,"path":615,"stem":616,"children":617,"page":42},"UniteLabs SDK","\u002Ftechnical-reference\u002Fpython-sdk","10.technical-reference\u002F20.python-sdk",[618,621],{"title":606,"path":619,"stem":620},"\u002Ftechnical-reference\u002Fpython-sdk\u002Finstall","10.technical-reference\u002F20.python-sdk\u002F10.install",{"title":610,"path":622,"stem":623},"\u002Ftechnical-reference\u002Fpython-sdk\u002Fchangelog","10.technical-reference\u002F20.python-sdk\u002F20.changelog",{"title":625,"path":626,"stem":627,"children":628,"page":42},"Liquid Handling SDK","\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk","10.technical-reference\u002F30.python-liquid-handling-sdk",[629,632],{"title":606,"path":630,"stem":631},"\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk\u002Finstall","10.technical-reference\u002F30.python-liquid-handling-sdk\u002F10.install",{"title":610,"path":633,"stem":634},"\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk\u002Fchangelog","10.technical-reference\u002F30.python-liquid-handling-sdk\u002F20.changelog",{"title":184,"path":636,"stem":637,"children":638,"page":42},"\u002Ftechnical-reference\u002Flabware","10.technical-reference\u002F40.labware",[639,642],{"title":606,"path":640,"stem":641},"\u002Ftechnical-reference\u002Flabware\u002Finstall","10.technical-reference\u002F40.labware\u002F10.install",{"title":610,"path":643,"stem":644},"\u002Ftechnical-reference\u002Flabware\u002Fchangelog","10.technical-reference\u002F40.labware\u002F20.changelog",{"title":646,"path":647,"stem":648,"children":649,"page":42},"Python Omnibus","\u002Ftechnical-reference\u002Fpython-omnibus","10.technical-reference\u002F50.python-omnibus",[650,653],{"title":606,"path":651,"stem":652},"\u002Ftechnical-reference\u002Fpython-omnibus\u002Finstall","10.technical-reference\u002F50.python-omnibus\u002F10.install",{"title":610,"path":654,"stem":655},"\u002Ftechnical-reference\u002Fpython-omnibus\u002Fchangelog","10.technical-reference\u002F50.python-omnibus\u002F20.changelog",{"title":657,"path":658,"stem":659,"children":660,"page":42},"Python CDK","\u002Ftechnical-reference\u002Fpython-cdk","10.technical-reference\u002F60.python-cdk",[661,664],{"title":606,"path":662,"stem":663},"\u002Ftechnical-reference\u002Fpython-cdk\u002Finstall","10.technical-reference\u002F60.python-cdk\u002F10.install",{"title":610,"path":665,"stem":666},"\u002Ftechnical-reference\u002Fpython-cdk\u002Fchangelog","10.technical-reference\u002F60.python-cdk\u002F20.changelog",{"title":668,"path":669,"stem":670,"children":671},"Connector Development (CDK)","\u002Fconnector-development","20.connector-development",[672,674,693,726,734,769],{"title":668,"path":669,"stem":673},"20.connector-development\u002Findex",{"title":675,"path":676,"stem":677,"children":678,"page":42},"Getting Started","\u002Fconnector-development\u002Fgetting-started","20.connector-development\u002F10.getting-started",[679,682,686,689],{"title":557,"path":680,"stem":681},"\u002Fconnector-development\u002Fgetting-started\u002Foverview","20.connector-development\u002F10.getting-started\u002F10.overview",{"title":683,"path":684,"stem":685},"What's new","\u002Fconnector-development\u002Fgetting-started\u002Fwhats-new","20.connector-development\u002F10.getting-started\u002F20.whats-new",{"title":77,"path":687,"stem":688},"\u002Fconnector-development\u002Fgetting-started\u002Finstallation","20.connector-development\u002F10.getting-started\u002F30.installation",{"title":690,"path":691,"stem":692},"Contributing","\u002Fconnector-development\u002Fgetting-started\u002Fcontributing","20.connector-development\u002F10.getting-started\u002F40.contributing",{"title":694,"path":695,"stem":696,"children":697,"page":42},"Tutorial","\u002Fconnector-development\u002Ftutorial","20.connector-development\u002F20.tutorial",[698,702,706,710,714,718,722],{"title":699,"path":700,"stem":701},"Walkthrough","\u002Fconnector-development\u002Ftutorial\u002Fwalkthrough","20.connector-development\u002F20.tutorial\u002F00.walkthrough",{"title":703,"path":704,"stem":705},"SiLA Endpoints","\u002Fconnector-development\u002Ftutorial\u002Fsila-endpoints","20.connector-development\u002F20.tutorial\u002F10.sila-endpoints",{"title":707,"path":708,"stem":709},"Data Endpoints","\u002Fconnector-development\u002Ftutorial\u002Fdata-endpoints","20.connector-development\u002F20.tutorial\u002F20.data-endpoints",{"title":711,"path":712,"stem":713},"Controls","\u002Fconnector-development\u002Ftutorial\u002Fcontrols","20.connector-development\u002F20.tutorial\u002F30.controls",{"title":715,"path":716,"stem":717},"SiLA Data Types","\u002Fconnector-development\u002Ftutorial\u002Fdata-types","20.connector-development\u002F20.tutorial\u002F40.data-types",{"title":719,"path":720,"stem":721},"Feature","\u002Fconnector-development\u002Ftutorial\u002Fconnector-structure","20.connector-development\u002F20.tutorial\u002F70.connector-structure",{"title":723,"path":724,"stem":725},"Hardware Communication","\u002Fconnector-development\u002Ftutorial\u002Fhardware-communication","20.connector-development\u002F20.tutorial\u002F90.hardware-communication",{"title":94,"path":727,"stem":728,"children":729,"page":42},"\u002Fconnector-development\u002Fconcepts","20.connector-development\u002F30.concepts",[730],{"title":731,"path":732,"stem":733},"SiLA","\u002Fconnector-development\u002Fconcepts\u002Fsila","20.connector-development\u002F30.concepts\u002Fsila",{"title":208,"path":735,"stem":736,"children":737,"page":42},"\u002Fconnector-development\u002Fguides","20.connector-development\u002F40.guides",[738,742,746,750,754,758,761,765],{"title":739,"path":740,"stem":741},"Configuration","\u002Fconnector-development\u002Fguides\u002Fconfiguration","20.connector-development\u002F40.guides\u002F20.configuration",{"title":743,"path":744,"stem":745},"Logging","\u002Fconnector-development\u002Fguides\u002Flogging","20.connector-development\u002F40.guides\u002F21.logging",{"title":747,"path":748,"stem":749},"Deployment","\u002Fconnector-development\u002Fguides\u002Fdeployment","20.connector-development\u002F40.guides\u002F30.deployment",{"title":751,"path":752,"stem":753},"Security","\u002Fconnector-development\u002Fguides\u002Fsecurity","20.connector-development\u002F40.guides\u002F40.security",{"title":755,"path":756,"stem":757},"Subscriptions","\u002Fconnector-development\u002Fguides\u002Fsubscriptions","20.connector-development\u002F40.guides\u002F45.subscriptions",{"title":204,"path":759,"stem":760},"\u002Fconnector-development\u002Fguides\u002Ferror-handling","20.connector-development\u002F40.guides\u002F50.error-handling",{"title":762,"path":763,"stem":764},"Serial Troubleshooting","\u002Fconnector-development\u002Fguides\u002Fserial-troubleshooting","20.connector-development\u002F40.guides\u002F70.serial-troubleshooting",{"title":766,"path":767,"stem":768},"Testing","\u002Fconnector-development\u002Fguides\u002Ftesting","20.connector-development\u002F40.guides\u002F80.testing",{"title":770,"path":771,"stem":772,"children":773},"References","\u002Fconnector-development\u002Freference","20.connector-development\u002F50.reference\u002Findex",[774],{"title":770,"path":771,"stem":772},{"id":776,"title":743,"body":777,"description":1646,"extension":1647,"links":1648,"meta":1649,"navigation":936,"path":744,"seo":1650,"stem":745,"__hash__":1651},"docs\u002F20.connector-development\u002F40.guides\u002F21.logging.md",{"type":778,"value":779,"toc":1641},"minimark",[780,797,814,826,857,862,890,894,897,960,979,996,999,1369,1373,1385,1391,1444,1450,1531,1541,1599,1605,1637],[781,782,784],"callout",{"icon":783},"i-heroicons-information-circle",[785,786,787,788,796],"p",{},"This guide focuses specifically on logging usage within the CDK. It should be enough for most people to get started. For a base-level introduction to Python logging, read the ",[789,790,795],"a",{"href":791,"rel":792,"target":794},"https:\u002F\u002Fdocs.python.org\u002F3\u002Fhowto\u002Flogging.html#logging-basic-tutorial",[793],"nofollow","_blank","Python standard library logging basic tutorial",".",[785,798,799,800,809,810,813],{},"Logging is essential for understanding a connector's behavior while debugging and in production.\nThe CDK provides a structured logging system built on top of ",[789,801,804],{"href":802,"rel":803,"target":794},"https:\u002F\u002Fwww.structlog.org\u002Fen\u002Fstable\u002F",[793],[805,806,808],"code",{"style":807},"color: green;","structlog"," and Python's standard ",[805,811,812],{},"logging"," module.\nOut of the box a connector emits human-readable logs to the terminal, and in production it additionally writes JSON-structured logs to a rotating file.",[785,815,816,817,821,822,796],{},"This guide covers how to ",[818,819,820],"strong",{},"emit logs from your own connector code",". For what a connector logs by default and how to customize its log output (levels, files, rotation), see ",[789,823,825],{"href":824},"\u002Fintegrate\u002Fconnect-a-device\u002Ffrom-source#logging","Connect a device — From source",[781,827,829],{"icon":828},"i-heroicons-light-bulb",[785,830,831,832,835,836,839,840,843,844,847,848,851,852,856],{},"To scaffold a config file pre-populated with the default logging presets, run ",[805,833,834],{},"config create"," with the ",[805,837,838],{},"--explicit-logging","\u002F",[805,841,842],{},"-x"," flag (defaults to ",[805,845,846],{},"prod","), e.g. ",[805,849,850],{},"uv run config create -x dev",". See ",[789,853,855],{"href":854},"\u002Fintegrate\u002Fconnect-a-device\u002Ffrom-source#customizing-the-logging-configuration","Customizing the logging configuration"," for the copyable available presets.",[858,859,861],"h2",{"id":860},"prerequisites","Prerequisites",[863,864,865,869],"ul",{},[866,867,868],"li",{},"CDK v0.13.0 or higher",[866,870,871,872,876,877,884,885,889],{},"A Connector, check out our ",[789,873,875],{"href":874},"\u002Fconnector-development\u002Fgetting-started\u002Finstallation\u002F","Installation Guide"," to create a new Connector project with our ",[789,878,881],{"href":879,"rel":880,"target":794},"https:\u002F\u002Fgitlab.com\u002Funitelabs\u002Fcdk\u002Fconnector-factory\u002F",[793],[805,882,883],{"style":807},"connector-factory"," cookiecutter and the ",[789,886,888],{"href":887},"\u002Fconnector-development\u002Ftutorial\u002Fwalkthrough\u002F","Connector Walkthrough"," to get started writing your own Connector.",[858,891,893],{"id":892},"logging-from-your-connector-code","Logging from your connector code",[785,895,896],{},"Wherever logging is required in a module of a connector, a logger can be created using:",[898,899,904],"pre",{"className":900,"code":901,"language":902,"meta":903,"style":903},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from unitelabs.cdk import get_logger\n\nlogger = get_logger(__name__)\n","python","",[805,905,906,931,938],{"__ignoreMap":903},[907,908,911,915,919,922,925,928],"span",{"class":909,"line":910},"line",1,[907,912,914],{"class":913},"s7zQu","from",[907,916,918],{"class":917},"sTEyZ"," unitelabs",[907,920,796],{"class":921},"sMK4o",[907,923,924],{"class":917},"cdk ",[907,926,927],{"class":913},"import",[907,929,930],{"class":917}," get_logger\n",[907,932,934],{"class":909,"line":933},2,[907,935,937],{"emptyLinePlaceholder":936},true,"\n",[907,939,941,944,947,951,954,957],{"class":909,"line":940},3,[907,942,943],{"class":917},"logger ",[907,945,946],{"class":921},"=",[907,948,950],{"class":949},"s2Zo4"," get_logger",[907,952,953],{"class":921},"(",[907,955,956],{"class":917},"__name__",[907,958,959],{"class":921},")\n",[785,961,962,965,966,968,969,971,972,975,976,978],{},[805,963,964],{},"get_logger"," returns a named logger instance.\n",[805,967,956],{}," is recommended to keep the logger names standard and clearly assigned to a module hierarchically by dotted path.\nNote that we call ",[805,970,964],{}," imported from the CDK and not ",[805,973,974],{},"logging.getLogger"," from Python's standard ",[805,977,812],{}," module.",[781,980,982],{"icon":981},"i-lucide-wrench",[785,983,984,985,987,988,990,991,995],{},"Using Python's standard ",[805,986,812],{}," still works without any additional setup and will be merged automatically with the CDK's internal structlog logs. We recommend the CDK's ",[805,989,964],{}," to get access to all structlog features (more details ",[789,992,994],{"href":993},"#structlog-features","below",")",[785,997,998],{},"Whenever a module or class requires a lot of logging, consider exposing the logger as a property to make the code more readable. Consider for example a protocol class:",[898,1000,1002],{"className":900,"code":1001,"language":902,"meta":903,"style":903},"from unitelabs.bus import Protocol\nfrom unitelabs.cdk import get_logger, BoundLogger\n\n\nclass DeviceProtocol(Protocol):\n    def __init__(self, ...):\n        ...\n\n    @property\n    def logger(self) -> BoundLogger:\n        \"\"\"A structured logger for this protocol.\"\"\"\n        return get_logger(__name__)\n\n    async def execute(self, command: str) -> None:\n        ...\n\n    async def make_device_do_something(self) -> str:\n        \"\"\"Make the device do science.\"\"\"\n        try:\n            await self.execute(\"start_science\")\n        except ValueError as exc:\n            self.logger.error(\"Failed to run `start_science`.\", exc_info=exc)\n            raise\n\n        self.logger.debug(\"Successfully ran `start_science`.\")\n",[805,1003,1004,1020,1040,1044,1049,1068,1090,1096,1101,1110,1133,1146,1160,1165,1200,1205,1210,1232,1242,1250,1277,1294,1332,1338,1343],{"__ignoreMap":903},[907,1005,1006,1008,1010,1012,1015,1017],{"class":909,"line":910},[907,1007,914],{"class":913},[907,1009,918],{"class":917},[907,1011,796],{"class":921},[907,1013,1014],{"class":917},"bus ",[907,1016,927],{"class":913},[907,1018,1019],{"class":917}," Protocol\n",[907,1021,1022,1024,1026,1028,1030,1032,1034,1037],{"class":909,"line":933},[907,1023,914],{"class":913},[907,1025,918],{"class":917},[907,1027,796],{"class":921},[907,1029,924],{"class":917},[907,1031,927],{"class":913},[907,1033,950],{"class":917},[907,1035,1036],{"class":921},",",[907,1038,1039],{"class":917}," BoundLogger\n",[907,1041,1042],{"class":909,"line":940},[907,1043,937],{"emptyLinePlaceholder":936},[907,1045,1047],{"class":909,"line":1046},4,[907,1048,937],{"emptyLinePlaceholder":936},[907,1050,1052,1056,1060,1062,1065],{"class":909,"line":1051},5,[907,1053,1055],{"class":1054},"spNyl","class",[907,1057,1059],{"class":1058},"sBMFI"," DeviceProtocol",[907,1061,953],{"class":921},[907,1063,1064],{"class":1058},"Protocol",[907,1066,1067],{"class":921},"):\n",[907,1069,1071,1074,1077,1079,1083,1085,1088],{"class":909,"line":1070},6,[907,1072,1073],{"class":1054},"    def",[907,1075,1076],{"class":949}," __init__",[907,1078,953],{"class":921},[907,1080,1082],{"class":1081},"s5tWE","self",[907,1084,1036],{"class":921},[907,1086,1087],{"class":917}," ...",[907,1089,1067],{"class":921},[907,1091,1093],{"class":909,"line":1092},7,[907,1094,1095],{"class":917},"        ...\n",[907,1097,1099],{"class":909,"line":1098},8,[907,1100,937],{"emptyLinePlaceholder":936},[907,1102,1104,1107],{"class":909,"line":1103},9,[907,1105,1106],{"class":921},"    @",[907,1108,1109],{"class":1058},"property\n",[907,1111,1113,1115,1118,1120,1122,1124,1127,1130],{"class":909,"line":1112},10,[907,1114,1073],{"class":1054},[907,1116,1117],{"class":949}," logger",[907,1119,953],{"class":921},[907,1121,1082],{"class":1081},[907,1123,995],{"class":921},[907,1125,1126],{"class":921}," ->",[907,1128,1129],{"class":917}," BoundLogger",[907,1131,1132],{"class":921},":\n",[907,1134,1136,1139,1143],{"class":909,"line":1135},11,[907,1137,1138],{"class":913},"        \"\"\"",[907,1140,1142],{"class":1141},"sHwdD","A structured logger for this protocol.",[907,1144,1145],{"class":913},"\"\"\"\n",[907,1147,1149,1152,1154,1156,1158],{"class":909,"line":1148},12,[907,1150,1151],{"class":913},"        return",[907,1153,950],{"class":949},[907,1155,953],{"class":921},[907,1157,956],{"class":917},[907,1159,959],{"class":921},[907,1161,1163],{"class":909,"line":1162},13,[907,1164,937],{"emptyLinePlaceholder":936},[907,1166,1168,1171,1174,1177,1179,1181,1183,1187,1190,1193,1195,1197],{"class":909,"line":1167},14,[907,1169,1170],{"class":1054},"    async",[907,1172,1173],{"class":1054}," def",[907,1175,1176],{"class":949}," execute",[907,1178,953],{"class":921},[907,1180,1082],{"class":1081},[907,1182,1036],{"class":921},[907,1184,1186],{"class":1185},"sHdIc"," command",[907,1188,1189],{"class":921},":",[907,1191,1192],{"class":1058}," str",[907,1194,995],{"class":921},[907,1196,1126],{"class":921},[907,1198,1199],{"class":921}," None:\n",[907,1201,1203],{"class":909,"line":1202},15,[907,1204,1095],{"class":917},[907,1206,1208],{"class":909,"line":1207},16,[907,1209,937],{"emptyLinePlaceholder":936},[907,1211,1213,1215,1217,1220,1222,1224,1226,1228,1230],{"class":909,"line":1212},17,[907,1214,1170],{"class":1054},[907,1216,1173],{"class":1054},[907,1218,1219],{"class":949}," make_device_do_something",[907,1221,953],{"class":921},[907,1223,1082],{"class":1081},[907,1225,995],{"class":921},[907,1227,1126],{"class":921},[907,1229,1192],{"class":1058},[907,1231,1132],{"class":921},[907,1233,1235,1237,1240],{"class":909,"line":1234},18,[907,1236,1138],{"class":913},[907,1238,1239],{"class":1141},"Make the device do science.",[907,1241,1145],{"class":913},[907,1243,1245,1248],{"class":909,"line":1244},19,[907,1246,1247],{"class":913},"        try",[907,1249,1132],{"class":921},[907,1251,1253,1256,1259,1261,1264,1266,1269,1273,1275],{"class":909,"line":1252},20,[907,1254,1255],{"class":913},"            await",[907,1257,1258],{"class":917}," self",[907,1260,796],{"class":921},[907,1262,1263],{"class":949},"execute",[907,1265,953],{"class":921},[907,1267,1268],{"class":921},"\"",[907,1270,1272],{"class":1271},"sfazB","start_science",[907,1274,1268],{"class":921},[907,1276,959],{"class":921},[907,1278,1280,1283,1286,1289,1292],{"class":909,"line":1279},21,[907,1281,1282],{"class":913},"        except",[907,1284,1285],{"class":1058}," ValueError",[907,1287,1288],{"class":913}," as",[907,1290,1291],{"class":917}," exc",[907,1293,1132],{"class":921},[907,1295,1297,1300,1302,1306,1308,1311,1313,1315,1318,1320,1322,1325,1327,1330],{"class":909,"line":1296},22,[907,1298,1299],{"class":917},"            self",[907,1301,796],{"class":921},[907,1303,1305],{"class":1304},"swJcz","logger",[907,1307,796],{"class":921},[907,1309,1310],{"class":949},"error",[907,1312,953],{"class":921},[907,1314,1268],{"class":921},[907,1316,1317],{"class":1271},"Failed to run `start_science`.",[907,1319,1268],{"class":921},[907,1321,1036],{"class":921},[907,1323,1324],{"class":1185}," exc_info",[907,1326,946],{"class":921},[907,1328,1329],{"class":949},"exc",[907,1331,959],{"class":921},[907,1333,1335],{"class":909,"line":1334},23,[907,1336,1337],{"class":913},"            raise\n",[907,1339,1341],{"class":909,"line":1340},24,[907,1342,937],{"emptyLinePlaceholder":936},[907,1344,1346,1349,1351,1353,1355,1358,1360,1362,1365,1367],{"class":909,"line":1345},25,[907,1347,1348],{"class":917},"        self",[907,1350,796],{"class":921},[907,1352,1305],{"class":1304},[907,1354,796],{"class":921},[907,1356,1357],{"class":949},"debug",[907,1359,953],{"class":921},[907,1361,1268],{"class":921},[907,1363,1364],{"class":1271},"Successfully ran `start_science`.",[907,1366,1268],{"class":921},[907,1368,959],{"class":921},[858,1370,1372],{"id":1371},"structlog-features","Structlog features",[785,1374,1375,1376,1378,1379,1384],{},"Using the ",[805,1377,964],{}," method from the CDK exposes a ",[789,1380,1382],{"href":802,"rel":1381,"target":794},[793],[805,1383,808],{}," bound logger. This means the following features are available:",[785,1386,1387,1390],{},[818,1388,1389],{},"Structured key-value context."," Pass keywords alongside the message; they become first-class fields in the JSON output instead of being baked into a string:",[898,1392,1394],{"className":900,"code":1393,"language":902,"meta":903,"style":903},"logger.info(\"Command finished\", command=\"start_science\", duration_ms=42)\n# JSON: {\"event\": \"Command finished\", \"command\": \"start_science\", \"duration_ms\": 42, ...}\n",[805,1395,1396,1439],{"__ignoreMap":903},[907,1397,1398,1400,1402,1405,1407,1409,1412,1414,1416,1418,1420,1422,1424,1426,1428,1431,1433,1437],{"class":909,"line":910},[907,1399,1305],{"class":917},[907,1401,796],{"class":921},[907,1403,1404],{"class":949},"info",[907,1406,953],{"class":921},[907,1408,1268],{"class":921},[907,1410,1411],{"class":1271},"Command finished",[907,1413,1268],{"class":921},[907,1415,1036],{"class":921},[907,1417,1186],{"class":1185},[907,1419,946],{"class":921},[907,1421,1268],{"class":921},[907,1423,1272],{"class":1271},[907,1425,1268],{"class":921},[907,1427,1036],{"class":921},[907,1429,1430],{"class":1185}," duration_ms",[907,1432,946],{"class":921},[907,1434,1436],{"class":1435},"sbssI","42",[907,1438,959],{"class":921},[907,1440,1441],{"class":909,"line":933},[907,1442,1443],{"class":1141},"# JSON: {\"event\": \"Command finished\", \"command\": \"start_science\", \"duration_ms\": 42, ...}\n",[785,1445,1446,1449],{},[818,1447,1448],{},"Bound loggers."," Pre-bind context that should appear on every subsequent log line from that logger:",[898,1451,1453],{"className":900,"code":1452,"language":902,"meta":903,"style":903},"log = logger.bind(device_id=\"A1B2\")\nlog.info(\"connected\")        # includes device_id\nlog.warning(\"timeout\")       # includes device_id\n",[805,1454,1455,1485,1508],{"__ignoreMap":903},[907,1456,1457,1460,1462,1464,1466,1469,1471,1474,1476,1478,1481,1483],{"class":909,"line":910},[907,1458,1459],{"class":917},"log ",[907,1461,946],{"class":921},[907,1463,1117],{"class":917},[907,1465,796],{"class":921},[907,1467,1468],{"class":949},"bind",[907,1470,953],{"class":921},[907,1472,1473],{"class":1185},"device_id",[907,1475,946],{"class":921},[907,1477,1268],{"class":921},[907,1479,1480],{"class":1271},"A1B2",[907,1482,1268],{"class":921},[907,1484,959],{"class":921},[907,1486,1487,1490,1492,1494,1496,1498,1501,1503,1505],{"class":909,"line":933},[907,1488,1489],{"class":917},"log",[907,1491,796],{"class":921},[907,1493,1404],{"class":949},[907,1495,953],{"class":921},[907,1497,1268],{"class":921},[907,1499,1500],{"class":1271},"connected",[907,1502,1268],{"class":921},[907,1504,995],{"class":921},[907,1506,1507],{"class":1141},"        # includes device_id\n",[907,1509,1510,1512,1514,1517,1519,1521,1524,1526,1528],{"class":909,"line":940},[907,1511,1489],{"class":917},[907,1513,796],{"class":921},[907,1515,1516],{"class":949},"warning",[907,1518,953],{"class":921},[907,1520,1268],{"class":921},[907,1522,1523],{"class":1271},"timeout",[907,1525,1268],{"class":921},[907,1527,995],{"class":921},[907,1529,1530],{"class":1141},"       # includes device_id\n",[785,1532,1533,1536,1537,1540],{},[818,1534,1535],{},"Exceptions."," Pass the exception via ",[805,1538,1539],{},"exc_info="," to attach a formatted traceback:",[898,1542,1544],{"className":900,"code":1543,"language":902,"meta":903,"style":903},"try:\n    ...\nexcept ValueError as exc:\n    logger.error(\"Validation failed\", exc_info=exc)\n",[805,1545,1546,1553,1558,1571],{"__ignoreMap":903},[907,1547,1548,1551],{"class":909,"line":910},[907,1549,1550],{"class":913},"try",[907,1552,1132],{"class":921},[907,1554,1555],{"class":909,"line":933},[907,1556,1557],{"class":917},"    ...\n",[907,1559,1560,1563,1565,1567,1569],{"class":909,"line":940},[907,1561,1562],{"class":913},"except",[907,1564,1285],{"class":1058},[907,1566,1288],{"class":913},[907,1568,1291],{"class":917},[907,1570,1132],{"class":921},[907,1572,1573,1576,1578,1580,1582,1584,1587,1589,1591,1593,1595,1597],{"class":909,"line":1046},[907,1574,1575],{"class":917},"    logger",[907,1577,796],{"class":921},[907,1579,1310],{"class":949},[907,1581,953],{"class":921},[907,1583,1268],{"class":921},[907,1585,1586],{"class":1271},"Validation failed",[907,1588,1268],{"class":921},[907,1590,1036],{"class":921},[907,1592,1324],{"class":1185},[907,1594,946],{"class":921},[907,1596,1329],{"class":949},[907,1598,959],{"class":921},[785,1600,1601,1604],{},[818,1602,1603],{},"Standard-library-style formatting"," also still works, so existing code needs no changes:",[898,1606,1608],{"className":900,"code":1607,"language":902,"meta":903,"style":903},"logger.info(\"Detected file change: %s\", path)\n",[805,1609,1610],{"__ignoreMap":903},[907,1611,1612,1614,1616,1618,1620,1622,1625,1628,1630,1632,1635],{"class":909,"line":910},[907,1613,1305],{"class":917},[907,1615,796],{"class":921},[907,1617,1404],{"class":949},[907,1619,953],{"class":921},[907,1621,1268],{"class":921},[907,1623,1624],{"class":1271},"Detected file change: ",[907,1626,1627],{"class":1435},"%s",[907,1629,1268],{"class":921},[907,1631,1036],{"class":921},[907,1633,1634],{"class":949}," path",[907,1636,959],{"class":921},[1638,1639,1640],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s5tWE, html code.shiki .s5tWE{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#F07178;--shiki-default-font-style:italic;--shiki-dark:#F07178;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":903,"searchDepth":910,"depth":933,"links":1642},[1643,1644,1645],{"id":860,"depth":933,"text":861},{"id":892,"depth":933,"text":893},{"id":1371,"depth":933,"text":1372},"How to emit logs from your connector code using the CDK and structlog.","md",null,{},{"title":743,"description":1646},"uDCrMBsW4u-8OjRIld8snToA2D_2IHgvsi0OwdqmNLg",[1653,1655],{"title":739,"path":740,"stem":741,"description":1654,"children":-1},"How to write dynamic configurations for connectors.",{"title":747,"path":748,"stem":749,"description":1656,"children":-1},"How to deploy connectors for production.",1784060390923]