CNC, robots & PLCs

Turn Machine Logs into queryable tables.

Turn the alarm and operation logs your CNC controls, robots and PLC gateways already write into SQL tables. Alarms, cycles, downtime and the inputs to OEE — without programming the PLC or rolling out an MES.

Use the results in Excel, Google Sheets, AI tools and your apps through the Database REST API.

Every connector type is on Free. Start with 2 data sources and 1 agent.

Machine LogsFiles read where they live
Inside your networkQuery Streams Network Agent

Read, organize and query on your machine.

Read-only queries · outbound connection

Source files stay in place. Your tools receive query results.

Source → agent → allowed results

Query Streams reads the log files machine controllers already write to disk and turns them into live SQL tables readable from Microsoft Excel, Google Sheets, AI assistants over MCP, the REST API and Power BI. Profiles ship for Mazak, KUKA, Homag, Fanuc, Haas, Okuma, Siemens, Heidenhain, Mitsubishi, Centroid, Hurco and Kawasaki controllers, and any other controller can be described by hand. Nothing is installed on the machine and nothing is uploaded; the agent reads the files where they land and only query results leave your network.

  • No PLC programming, no MES
  • Twelve controller families built in
  • Alarms, cycles and downtime as SQL

Connect Machine Logs with the right settings.

Keep the connection on the Network Agent. These are the details specific to Machine Logs.

Folder
Wherever the control already writes - local disk or a network share typed as \\server\share (never a mapped drive letter; on Linux or a Mac, mounted first); subfolders included, include and exclude patterns supported
Format
Pinned by the controller's profile - record boundary, grammar, timestamp format and column names all come with it
Controllers
Mazak, KUKA, Homag, Fanuc, Haas, Okuma, Siemens, Heidenhain, Mitsubishi, Centroid, Hurco and Kawasaki, plus a describe-it-yourself mode for anything else
Rotation
Understood, not worked around - ten named rotation patterns plus plain unrotated files, compressed archives included
Unmatched lines
Kept verbatim in events_raw_lines, never dropped
Credentials
None - there is no server; the agent reads the files in place
SQL dialect
DuckDB - standard SQL, nothing machine-specific to learn

Nothing is installed on the machine control and no PLC logic is touched. The controller keeps writing the log it has always written; the agent reads that file from a machine that can see the folder, caches the parsed rows in an encrypted store beside itself, and re-reads only the bytes that are new. If the shop network is offline, the log is still on the control and the next sync catches up.

Built for how Machine Logs works.

What comes out

  • One row per logged event, with the timestamp the control wrote, the alarm or message code, its text, and _source_file naming the machine it came from.
  • Alarm histories, operation histories and message logs, depending on what the controller keeps - the profile knows which files matter and which are noise.
  • Every control in the shop lands in one table, so "which machine stopped most this month" is a GROUP BY rather than a walk round the floor.
  • Lines a profile does not recognise are kept verbatim in events_raw_lines, so an unusual alarm format is still a question you can answer.
-- Downtime hotspots by machine, this month
SELECT   _source_file AS machine, code, COUNT(*) AS hits
FROM     fileset.events
WHERE    severity = 'ALARM'
GROUP BY machine, code
ORDER BY hits DESC

When your controller is not on the list

Twelve controller families ship with a profile, and "any other controller" is a real answer rather than a brush-off: the log driver's custom mode lets you describe the record boundary, grammar, timestamp and columns yourself, once, and the folder becomes a table like any other. If you would rather it were built in, ask - profiles are added on request.

The formats and behavior, in detail.

Open the reference you need for Machine Logs.

A folder of controller logs becomes a downtime table.
The big idea

A folder of controller logs becomes a downtime table.

Query Streams reads the files the control already writes, pins their format, and derives the tables a plant actually asks for. The raw lines stay queryable too — a line the parser cannot read is kept as a row with a reason, never silently dropped.

Controller fileson a share
OPRT_HIS.TXTFANUC
AlarmHistory.txtHaas
msg_log.txtCentroid

Rotations, re-punched exports and duplicate lines — handled

availability.sqlSQL
SELECT date, identity,
       running_s / planned_s AS availability,
       down_unplanned_s, small_stops
FROM   fileset.oee_inputs
WHERE  identity = 'MILL-04'
ORDER BY date DESC
Resultoee_inputs
dateunplannedavail
03-1442m86.1%
03-1318m93.4%
03-1271m78.2%
03-119m95.8%

Join it to your ERP work orders in the same query

Files the machine already writes, now a table you can report on

Twelve controller brands, out of the box
Controllers

Twelve controller brands, out of the box

Each card names the exact files Query Streams reads on that controller, where they come from, and how the file behaves — appended live, rewritten whole on every export, or one new file per event.

Supported controller logs

19 formats · 12 brands
Mazak logo - Query Streams reads Mazak MTConnect SHDR machine logs MazakMTConnect
  • /shdr/*.txt MTConnect adapter stream capture
  • One file per machine per day
  • Appends live while the machine runs
KUKA logo - Query Streams reads KUKA Logbuch robot controller exports KUKARobot controller
  • Logbuch_*.txt controller diagnostics export
  • UTF-16 text, decoded for you
  • Rewritten in full on every export
H HomagwoodWOP / CutRite
  • woodWOP NC run file, written at Cycle Start
  • .prl .ctt .pct CutRite planning files, eleven per optimisation
  • One new file per run
FANUC logo - Query Streams reads FANUC operation history and robot alarm logs Fanuc30i / 31i · robots
  • OPRT_HIS.TXT operation history, punched from the control
  • MD/ERRALL.LS robot alarm history from a controller backup
  • Ring buffer — re-punched whole, never appended
Haas logo - Query Streams reads Haas CNC alarm history logs HaasSystem Data backup
  • AlarmHistory.txt alarm history with codes and timestamps
  • Unzipped from HaasBackup(mm-dd-yyyy) on the USB stick
  • One new file per backup
Okuma logo - Query Streams reads Okuma OSP alarm history logs OkumaOSP control
  • ALARM_HISTORY.DAT OSP alarm history
  • From the NCBACKUP folder of a control backup
  • Rewritten whole each backup
Siemens logo - Query Streams reads Siemens SINUMERIK action and alarm logs SiemensSINUMERIK
  • ac_log/*.log HMI action log and alarm log
  • From /user/sinumerik/hmi/ac_log on the control
  • Rewritten whole on export
Heidenhain logo - Query Streams reads Heidenhain TNC logbook files HeidenhainTNC control
  • TNC:\LOGBOOK.A control logbook dump
  • Pulled with MOD code LOGBOOK, or TNCremo
  • Rewritten whole on each dump
Mitsubishi Electric logo - Query Streams reads Mitsubishi M7 and M8 alarm logs MitsubishiM7 / M8
  • LOG\ALMLOG.LOG alarm log
  • From a control backup written to a memory card
  • Rewritten whole each backup
Centroid logo - Query Streams reads Centroid CNC12 message logs CentroidCNC12
  • c:\cncm\msg_log.txt message log — cnct on a lathe
  • Also read from the F7 Create Report zip
  • Appends, then trims from the head — handled without losing rows
Hurco logo - Query Streams reads Hurco WinMax NavErr and NavESTOP event files HurcoWinMax
  • Output Files\NavErr one file per error
  • Output Files\NavESTOP one file per E-stop
  • New file per event, folder grows without limit
Kawasaki Robotics logo - Query Streams reads Kawasaki robot ERRLOG files KawasakiRobotics
  • ERRLOG robot error log
  • Saved with the controller data backup (SAVE / ELOG)
  • Rewritten whole each backup
Any other controllerFour generic shapes
CNC controller syslog icon PLC key-value telemetry icon Robot controller JSON lines icon Laser cutter CSV export icon
  • Logs/*_YYYY-MM-DD.log CNC controller syslog
  • Logs/plc*.log PLC key=value telemetry
  • *.jsonl robot controller JSON lines
  • *_YYYYMMDD.csv headerless laser CSV, decimal comma
More comingthese are the start, not the ceiling

New controller formats are added with each Agent release. Because Agents keep themselves up to date, a controller supported later shows up in your connector without anyone walking a USB stick to a machine.

The Mazak, KUKA and HOMAG parsers were built and tested against real files captured from the machine. The rest were built to the vendor’s documented format. Send us a sample from yours and we will verify it against the real thing.
Controller logs from every plant, read where the machine is
Every plant

Controller logs from every plant, read where the machine is

A controller log is stranded by default. It sits on the machine or on a share on the shop floor, behind a plant firewall, in a building your reporting tools were never going to reach. Each plant runs a Network Agent that reads those files in place and dials out to Query Streams. As far as the plant firewall is concerned that is an ordinary outbound connection — nothing to open, no site-to-site VPN, and no ticket per machine.

Plant 1 FANUC and Haas controllers writing to one shared folder dials out
Plant 2 Okuma and Mitsubishi, alarm exports dropped nightly dials out
Contract shop A single Centroid mill and the PC beside it dials out

Three outbound connections, one place to query them — no inbound port, no VPN, no firewall change

One Agent per plant

An Agent covers a whole site rather than a single machine: every controller share at that plant becomes its own File Set connector on the same Agent. The Free plan runs a single Agent and paid plans run more.

1 plant = 1 Agent = many controllers

Nothing to open

The Agent makes one encrypted outbound connection, and the request out and the rows back both travel over it. No inbound port, no site-to-site VPN, and nothing for plant IT to expose — credentials stay inside the plant network.

one connection, both directions

One query across plants

Every source in a federated query names its own Agent, so a single statement can compare downtime at two plants on different continents, or join either of them to your ERP work orders. Included on Business and Enterprise.

2 plants → 1 result set

They keep themselves current

Agents update themselves, so a controller format added in a later release reaches every plant without anyone walking a USB stick onto the shop floor. That is what makes the wall above a starting point rather than a fixed list.

new formats arrive with the Agent

Machine logs do not behave like server logs

Machine logs do not behave like server logs

A controller rarely appends politely to one growing file. Query Streams recognises four different growth patterns, so re-punched exports and trimmed logs do not turn into duplicate rows.

Append

The familiar case — new lines are added to the end of the file and the earlier lines never move.

MTConnect SHDR capture · CNC syslog

Append with head trim

Lines are appended, then the control periodically deletes lines from the top to cap the file size. Following a byte offset alone would silently skip data.

Centroid CNC12 msg_log.txt

Snapshot rewrite

Every export rewrites the whole file from a fixed-size ring buffer in the control. Two exports overlap heavily, so the overlap has to be recognised rather than re-imported.

FANUC OPRT_HIS.TXT · Okuma · Heidenhain · Kawasaki

One file per event

The control writes a brand new file for each alarm, estop or program run. The folder grows in file count, not file size.

Hurco NavErr · Haas · HOMAG woodWOP

From log lines to the five tables a plant reports on
Derived tables

From log lines to the five tables a plant reports on

Parsing is the easy half. Query Streams turns parsed lines into interval tables — then into the availability inputs your OEE board needs.

alarmsEvery alarm as an interval, with a start, an end and a duration — not just a timestamp.
identitycodeseverityconditionts_startts_endduration_splanned
cyclesProgram runs with their cycle time, the part produced and whether it was good.
identityprogrampartstartendcycle_sgood
idle_intervalsEvery gap the machine was not running, classified by reason and mapped to a SEMI E10 state and an OEE loss bucket.
identitystartendduration_sreasonplannede10_stateoee_losspbtalarm_code
shiftsThe shift calendar the intervals are measured against, including unworked shifts.
identitydateshiftstartendplanned_s
oee_inputsOne row per machine per day: planned time, running time, and every loss bucket accounted for.
identitydateplanned_srunning_ssetup_sdown_planned_sdown_unplanned_ssmall_stop_ssmall_stopsdown_undetermined_spartsscrap

The seconds add up: planned time always equals running plus setup plus every down bucket — no unexplained time.

Aligned to the standards your plant already reports in

Aligned to the standards your plant already reports in

The classification vocabulary is not invented. It follows the published models, so the numbers reconcile with what your quality and continuous-improvement teams already use.

SEMI E10 states

Every idle interval resolves to one of the six standard equipment states.

productivestandbyengineeringscheduled_downunscheduled_downnon_scheduled
ISO 22400-2 time model

Availability is computed the way the standard defines it — actual production time over planned busy time — with planned stops inside the shift window treated as availability losses.

running_s / planned_s
The six big losses

Downtime lands in a named loss bucket, including an honest bucket for time we cannot attribute.

planned_stopunplanned_stopsmall_stopslow_cycleproduction_rejectstartup_rejectundetermined
Reason codes

A small, fixed reason vocabulary drives the mapping — and a reason we cannot resolve is reported by name rather than guessed.

breakno-worksetupmaintenancealarmoffengineering

From connection to useful results.

  1. Find where the controller already writes its logs - a folder on the control, a share it drops files onto, or the folder your existing collection script writes to.
  2. Install the Network Agent on a machine that can see that folder. Nothing is installed on the control itself and nothing is programmed.
  3. Pick the controller's profile. The record boundary, grammar, timestamp format and column names are pinned by the profile, so there is nothing to describe.
  4. The agent reads only the new bytes in each file from then on, understands the controller's rotation, and keeps unmatched lines rather than dropping them.
  5. Query it. Alarms by machine and shift, mean time between failures, cycle counts, downtime reasons - ordinary SQL over every control at once.

Put your Machine Logs results to work.

One connection serves your spreadsheets, apps and AI tools. Share permission to run a saved query; recipients see the allowed results, with the SQL and source login hidden.

For your team, vendors and partners

Ask a question in plain English. Nova already knows your Machine Logs tables, writes and runs the SQL, explains the answer and charts it — no query to write, no credentials to hand over.

How Nova works

Share a live Machine Logs result with anyone — a colleague, a vendor, a partner — as a bookmarkable grid that re-runs fresh when opened, on a phone, a tablet or a desktop. They see the results, never the SQL or the files.

How the Data Viewer works

For apps and systems

Publish a Machine Logs query as an authenticated JSON endpoint any application can call, with an OpenAPI 3.1 spec and ready-made Postman, Insomnia and Hoppscotch collections. No database port is opened.

Explore REST API

Paste the generated Power Query M into the Power BI Advanced Editor and the report reads live Machine Logs results over HTTPS — no ODBC driver, no database port opened.

Explore Power BI

For AI tools

Delivered to people

Join Machine Logs to the rest of your data.

Bring databases, business APIs, files and logs into one read-only query. Every connector supports Federated Queries.

Name the connections and tables. Query Streams handles the source queries and combines the results.

Explore Federated Queries
Illustrative cross-source query
-- nothing copied, nothing merged, nothing scheduled
SELECT   c.region, COUNT(*) AS orders, SUM(i.amount_due) AS invoiced
FROM     machinelogs.fileset.orders1 f
JOIN     pg_crm.public.customers2    c ON c.id = f.customer_id
JOIN     billing.stripe.invoices3    i ON i.customer = c.stripe_id
GROUP BY c.region
ORDER BY invoiced DESC;

Use your own connection, schema, table and column names.

Shared across the connector family.

Every log connector also gives you

  • events — one row per parsed line, with the timestamp, the fields the grammar named, and _source_file naming the file it came from.
  • events_raw_lines — lines the grammar did not match, kept verbatim rather than dropped, so a format you did not anticipate is a question you can still answer.
  • files_current and files_events — the live inventory and the audit trail: what appeared, what rotated, what vanished, and anything held back, with the filename and the reason.
  • Rotation is understood, not worked around — ten named rotation patterns plus plain unrotated files, so yesterday's log and its compressed archive are the same table as today's.

Good to know

  • Read-only, enforced — one statement at a time, SELECT and friends only. Your logs are never written, moved, rotated or truncated by us.
  • Nothing is uploaded — lines are parsed and cached, encrypted, on your own machine beside the agent. Only the result of a query leaves your network.
  • Only new bytes are read — the agent resumes where it left off in each file rather than re-reading it, so a busy log does not cost more every day.
  • The SQL dialect is DuckDB — the same SQL you would write against any other connector.

Questions about Machine Logs

Where can I use Machine Logs query results?

Use Machine Logs results in Excel, Google Sheets, the Data Viewer, your apps through the Database REST API, and AI tools through MCP or Nova. Saved results also feed supported Automation destinations, reports and alerts. Destination availability and allowances depend on your plan.

Do I need to open an inbound port for Machine Logs?

No. Install the Network Agent on a machine that can reach Machine Logs. The agent connects outward to Query Streams; no inbound port or VPN is needed. Your source must still allow the agent machine to connect under its own access rules.

Are my Machine Logs files uploaded?

The Network Agent reads files where they are and keeps its cache on the agent machine. Source files are not uploaded, moved or rewritten. Only requested query results leave your network over the outbound encrypted connection.

What do I need to connect Machine Logs?

Folder: Wherever the control already writes - local disk or a network share typed as \\server\share (never a mapped drive letter; on Linux or a Mac, mounted first); subfolders included, include and exclude patterns supported. Format: Pinned by the controller's profile - record boundary, grammar, timestamp format and column names all come with it. Controllers: Mazak, KUKA, Homag, Fanuc, Haas, Okuma, Siemens, Heidenhain, Mitsubishi, Centroid, Hurco and Kawasaki, plus a describe-it-yourself mode for anything else. Rotation: Understood, not worked around - ten named rotation patterns plus plain unrotated files, compressed archives included

Can I join Machine Logs to other connected sources?

Yes. Federated Queries support every connector type, including databases, business APIs, files and logs. Name the connections and tables in one read-only query. Query Streams translates the source portions as needed and combines their results. See how Federated Queries work.

Do I have to install anything on the machine control?

No. Query Streams reads files, so nothing is installed on the control and nothing is written back to it. You point a Query Streams Agent at whatever folder the logs already reach — a network share, the folder a USB backup gets copied into, or the machine PC. Access is read-only.

Have you actually seen my controller’s logs, or just the documented format?

Both cases exist, and it is worth knowing which one you are in. Three brands have parsers built and tested against real files captured off the machine: Mazak via MTConnect, KUKA, and HOMAG. The other nine were built against the vendor’s published format description.

Every one of them is supported and tested — but we would rather say this plainly than let you assume we have seen your exact control. If yours is in the second group and something does not parse, send us a sample and it moves into the first.

My control is not on the list. Is it out of luck?

Probably not. Alongside the twelve named brands there are four generic shapes that cover a great deal of shop-floor equipment: CNC controller syslog, PLC key=value telemetry, robot JSON lines, and headerless CSV exports of the kind laser cutters produce. If your log looks like any of those, it will read.

What happens to lines that do not parse?

They are kept. An unparsed line is stored as a row carrying the reason it could not be read, so it stays visible and queryable. The same applies at file level — a file that no longer matches the pinned format is parked and reported rather than quietly merged in. You can always account for every line in the folder.

Can I join machine downtime to my ERP data?

Yes — that is the point of putting logs in SQL. A federated query can join the derived idle_intervals or oee_inputs tables to work orders, part masters or schedules living in a completely separate SQL Server, Postgres or MySQL database, and return one joined result set.

Is this a log monitoring or alerting product?

No, and we would rather be clear about it. This is not a log shipping pipeline or an operations monitoring platform. It makes existing log files queryable with SQL and reportable in a spreadsheet. If you need streaming ingest and real-time alerting at infrastructure scale, that is a different category of tool.

Put Machine Logs where the work happens.

Start with Free: every connector type, 2 data sources and 1 Network Agent. Add plan allowances as your needs grow.