Using Mobile Execution Commands to Continuously Stream Device Logs with Appium

February 25, 2026 · 8 min read · Mobile Testing

HeadSpin Platform
Automated & amp; manual testing create easy through data science insights.
Differentiating capacity:
  • Extensive end-to-end mechanization of QA process
  • Relative analysis of app performance against peers
  • Continuous monitoring of app execution using synthetic data for higher availability of apps
  • Easy-to-use developer friendly program
cloudtest go
Affordable Existent Device Testing for Emerging Teams
cloudtest go
Affordable Existent Device Testing for Digital Enterprises
cloudtest go
The Ultimate Solution for a Powerful Blend of Functional & amp; Performance Testing!
cyol
TEM
New
Centralized peregrine examination execution in cloud
cyol
Enhance Your Accessibility Testing With HeadSpin
cyol
Automate camera-based testing

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

retail

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

Using Mobile Execution Commands to Continuously Stream Device Logs with AppiumUsing Mobile Execution Commands to Continuously Stream Device Logs with Appium

Using Mobile Execution Commands to Continuously Stream Device Logs with Appium

Published on
February 6, 2019
Updated on
Published on
April 26, 2022
Updated on
 by 
 Jonathan LippsJonathan Lipps
Jonathan Lipps

I recently wrote about using the getLogs () command, but Appium also indorse subscribing to device logs as a stream of event via a WebSocket connection. Rather than getting a lump of recent log lines every time a synchronous call to getLogs () is create, you can assign a function to be called every clip a new log line is generated. Overall, this results in a better programming model for most cases, and simply adds a little more code depending on the language.

Appium needs to be told to start its WebSocket server before we can begin listening for log messages. This is done using one of theparticular mobile: commands.

Pro tip: Tools like SUSA can handle this autonomously — upload your app and get results without writing a single test script.

driver.executeScript (`` mobile: startLogsBroadcast '');

Appium will start a WebSocket waiter and accept connecter on the like legion and port to which you connected to start the test session. The path is different though; alternatively of /wd/hub the path starts with /ws:

  • /ws/session/ {sessionId} /appium/device/logcat for Android logcat log
  • /ws/session/ {sessionId} /appium/device/syslog for iOS device log

WebSocket URLs start with ws: // instead of http: //. Running locally with the default Appium port, the WebSocket URLs would be:

  • ws: //localhost:4723/ws/session/ {sessionId} /appium/device/logcat on Android
  • ws: //localhost:4723/ws/session/ {sessionId} /appium/device/syslog on iOS

Using a WebSocket node and connecting to these URLs, we can assign a role to do whatever action we want whenever a new log message is received.

There are several advantages of swarm logs this way. By using streams, we are only holding a single log message in memory at a clip. If the device logs are real long, calling getLogs () and lade all the device logs could take a spell and even consume too much memory on our exam servers. We are also able to get sure that we have the modish logs available. If an elision is cast in our test code, or a crash occurs in the app, device, or Appium server, we can be sure that we experience the last log message which create its way through our scheme (which is most likely to contain information about the clank!). This will work better than catch exception and so name getLogs (), for by then it may be too late to reach the gimmick. We can besides abstract the log-handling code further from our test code. By writing multiple WebSocket guest, we can change how logs are handled look on the system environs.

For our Java example, I usedTooTallNates & # x27; s java-websocket software. I & # x27; m also including a JavaScript example use websocket-stream

importee io.appium.java_client.AppiumDriver; meaning org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; significance org.junit.Test; import org.openqa.selenium.remote.DesiredCapabilities; import java.net.MalformedURLException; import java.net.URI; importee java.net.URISyntaxException; import java.net.URL; public class Edition055_ADB_Logcat_Streaming {private String ANDROID_APP = `` https: //github.com/cloudgrey-io/the-app/releases/download/v1.8.1/TheApp-v1.8.1.apk ''; individual String IOS_APP = `` https: //github.com/cloudgrey-io/the-app/releases/download/v1.6.1/TheApp-v1.6.1.app.zip ''; individual AppiumDriver driver; public class LogClient extends WebSocketClient {public LogClient (URI serverURI) {super (serverURI);} @ Override public vacancy onOpen (ServerHandshake handshakedata) {System.out.println (`` WEBSOCKET OPENED '');} @ Override public nullity onMessage (String message) {System.out.println (message);} @ Override public emptiness onClose (int code, String reason, boolean remote) {System.out.println (`` Connection closed, log streaming has stopped '');} @ Override public void onError (Exception ex) {ex.printStackTrace (); // if the mistake is fateful then onClose will be called additionally}} @ Test public void streamAndroidLogs () throw URISyntaxException, MalformedURLException {DesiredCapabilities caps = new DesiredCapabilities (); caps.setCapability (`` platformName '', `` Android ''); caps.setCapability (`` deviceName '', `` Android Emulator ''); caps.setCapability (`` automationName '', `` UiAutomator2 ''); caps.setCapability (`` app '', ANDROID_APP); driver = new AppiumDriver (new URL (`` http: //localhost:4723/wd/hub ''), cap); LogClient logClient = new LogClient (new URI (`` ws: //localhost:4723/ws/session/ '' + driver.getSessionId () + `` /appium/device/logcat '')); driver.executeScript (`` mobile: startLogsBroadcast ''); logClient.connect (); try {Thread.sleep (5000);} catch (Exception ign) {} // logarithm printed to stdout while we 're sleeping. driver.executeScript (`` mobile: stopLogsBroadcast ''); driver.quit ();} @ Test public void streamIOSLogs () throws URISyntaxException, MalformedURLException {DesiredCapabilities caps = new DesiredCapabilities (); caps.setCapability (`` platformName '', `` iOS ''); caps.setCapability (`` platformVersion '', `` 12.1 ''); caps.setCapability (`` deviceName '', `` iPhone XS ''); caps.setCapability (`` automationName '', `` XCUITest ''); caps.setCapability (`` app '', IOS_APP); driver = new AppiumDriver (new URL (`` http: //localhost:4723/wd/hub ''), caps); LogClient logClient = new LogClient (new URI (`` ws: //localhost:4723/ws/session/ '' + driver.getSessionId () + `` /appium/device/syslog '')); driver.executeScript (`` mobile: startLogsBroadcast ''); logClient.connect (); try {Thread.sleep (5000);} catch (Exception ign) {} // logarithm publish to stdout while we 're sleep. driver.executeScript (`` mobile: stopLogsBroadcast ''); driver.quit ();}}

And the Javascript example:

let test = require ('ava ') let {remote} = require ('webdriverio ') let B = require ('bluebird ') let websocket = require ('websocket-stream ') let driver test ('stream Android logcat logarithm ', async t = > {driver = await remote ({hostname: 'localhost ', embrasure: 4723, path: '/wd/hub ', capabilities: {platformName: 'Android ', deviceName: 'Android Emulator ', automationName: 'UiAutomator2 ', app: 'https: //github.com/cloudgrey-io/the-app/releases/download/v1.8.1/TheApp-v1.8.1.apk'}, logLevel: 'error'}) let logStream = websocket (` ws: //localhost:4723/ws/session/ $ {driver.sessionId} /appium/device/logcat `) logStream.pipe (process.stdout) logStream.on ('finish ', () = > {console.log ('Connection fold, log streaming has cease ')}) driver.executeScript ('mobile: startLogsBroadcast ', []) await B.delay (5000) driver.executeScript ('mobile: stopLogsBroadcast ', []) await driver.deleteSession () t.pass ()}) test ('stream iOS system logs ', async t = > {driver = await remote ({hostname: 'localhost ', port: 4723, path: '/wd/hub ', capability: {platformName: 'iOS ', platformVersion: '12.1 ', deviceName: 'iPhone XS ', automationName: 'XCUITest ', app: 'https: //github.com/cloudgrey-io/the-app/releases/download/v1.6.1/TheApp-v1.6.1.app.zip'}, logLevel: 'error'}) let logStream = websocket (` ws: //localhost:4723/ws/session/ $ {driver.sessionId} /appium/device/syslog `) logStream.pipe (process.stdout) logStream.on ('finish ', () = > {console.log ('Connection fold, log streaming has stopped ')}) driver.executeScript ('mobile: startLogsBroadcast ', []) await B.delay (5000) driver.executeScript ('mobile: stopLogsBroadcast ', []) look driver.deleteSession () t.pass ()})

(Both variation of the full code demonstration are useableon GitHub)

Author & # x27; s Profile

Jonathan Lipps

LinkedIn
Author & # x27; s Profile

Piali Mazumdar

Lead, Content Marketing, HeadSpin Inc.

Piali is a dynamic and results-driven Content Marketing Specialist with 8+ years of experience in crafting engross narratives and marketing collateral across diverse industries. She excels in collaborating with cross-functional teams to germinate innovational content strategies and deliver compelling, authentic, and impactful content that resonates with target hearing and enhances brand authenticity.

LinkedIn

Using Mobile Execution Commands to Continuously Stream Device Logs with Appium

4 Parts

regression intelligence blog
-

Regression Intelligence practical guide for modern exploiter (Part 3)

Coming Soon
Regression Intelligence practical guide for advanced users
-

Regression Intelligence hardheaded guide for advanced users (Part 4)

Coming Soon

Discover how HeadSpin can gift your business with superior testing capability

Our Platform enable you to:
accelerate time-to-market
Accelerate time-to-market, gaining a competitive edge
faster development cycles
Boost developer/QA productivity with faster development cycles
automated buil-over-build regression testing
Automate build-over-build regression testing for consistent results
gain better visibility into functional & performance issues
Gain better visibility into functional and performance issues
reduce mean time
Reduce mean clip to identify/resolve during test, QA, and product
evaluate audio, video & qoe
Evaluate audio, video, and content caliber of experience (QoE) effortlessly
The trusted choice for global enterprises
Adobe
Hargreaves Lansdown
Truecaller
Crazylabs
Nedbank
Numeracle
Veryon
Close

Discover how HeadSpin can gift your business with superior prove capableness

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gaining a competitive edge
faster development cycles
Boost developer/QA productiveness with quicker ontogenesis cycles
automated buil-over-build regression testing
Automate build-over-build fixation test for coherent results
gain better visibility into functional & performance issues
Gain better visibility into functional and execution issues
reduce mean time
Reduce mean time to identify/resolve during test, QA, and product
evaluate audio, video & qoe
Evaluate audio, video, and contented character of experience (QoE) effortlessly
The sure choice for global endeavor
Close

Discover how HeadSpin can empower your business with superior examine capability

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gaining a free-enterprise edge
faster development cycles
Boost developer/QA productivity with faster development cycles
automated buil-over-build regression testing
Automate build-over-build regression essay for consistent results
gain better visibility into functional & performance issues
Gain better visibility into functional and performance issues
reduce mean time
Reduce mean time to identify/resolve during test, QA, and production
evaluate audio, video & qoe
Evaluate sound, video, and content caliber of experience (QoE) effortlessly
The trusted alternative for globose enterprises
Close

Connet Now

Wipro LogoVMLYR Logo
Close
Book a Meeting
Products
footer down arrow
Solutions
footer down arrow
Industries
footer down arrow
Features
footer down arrow
Support
footer down arrow
Resource Center
footer down arrow
Why Choose HeadSpin?
footer down arrow
Copyright © 2026 HeadSpin, Inc. All Rights Reserved.

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free