Apple unified logging - how to get file name and line number - ios

Apple's Unified Logging documentation states:
Don’t include symbolication information or source file line numbers in messages. The system automatically captures this information.
But in Console I don't see a filename, class name, function name, or line numbers.
How can I have those in my logs?

Indeed, even macOS Catalina beta (build 19A501i) does not show source lines in Console.app.
However, the log command line tool does show source information for simulated devices (macOS 10.14 onwards).
The following command will show log information for all simulated devices currently booted (running) in the simulator. If no simulated devices are currently running the command will fail.
xcrun simctl spawn booted log stream --level debug --color always --source
You can filter out everything which does not come from your program by using a subsystem in os_log calls, and applying a predicate to the streamed logged data. For example, if your subsystem is com.subsystem.my, you can use
xcrun simctl spawn booted log stream --level debug --color always --predicate '(subsystem BEGINSWITH "com.subsystem.my")' --source
The source code information will be shown after the TTL column.
You can also filter by process (i.e. the name of your target), in case you didn't set up a subsystem
xcrun simctl spawn booted log stream --level debug --color always --predicate '(process == "MyProcess")' --source
However, this will normally result in too many log messages since information logged by other frameworks will also be included.
Also, instead of booted, you can use the name of the actual simulated device (to stream log data from that device alone).

os_log doesn't currently give line numbers/function names for Swift code in Console.app, or through the log stream command.
If you really need it - you can use Literal Expressions to pass the information manually via NSLog or os_log like this:
os_log(.info, "Log message from file: %s, line: %i, column: %i", #file, #line, #column)
It may be tempting to wrap os_log to always include this information, but Apple suggests not doing so for performance reasons.

Till apple fixes this issue,
I've created a simple extension
import os
extension Logger {
init(subsystem: String = Bundle.main.bundleIdentifier ?? "", file: String = #file, function: String = #function, line: Int = #line, context: String) {
let category = "\(file):\(line):\(function), \(context)"
self.init(subsystem: subsystem, category: category )
}
}
Usages:
Logger(context: "LoginFLow").debug("Hello World")
We can even remove param name to make it more cleaner:
import os
extension Logger {
init(subsystem: String = Bundle.main.bundleIdentifier ?? "", file: String = #file, function: String = #function, line: Int = #line, _ context: String) {
let category = "\(file):\(line):\(function), \(context)"
self.init(subsystem: subsystem, category: category )
}
}
Usages:
Logger("LoginFLow").debug("Hello World")
Note: If you wish to use the original Logger, just remove the context param and it will use its original init provided by apple.
Logger().debug("Hello World")

Related

Running `.dart` files does not show logging messages

I just cannot figure out how to show logging messages when running dart files from terminal.
Example example.dart:
import 'dart:developer';
void main() {
print('print');
log('log');
}
Expected output:
print
log
Actual output:
print
I tried calling dart example.dart, dart run --all example.dart, dart run --verbosity=all example.dart, and different values instead of all (info, ...).
But non of these produced any helpful error messages let alone the out print I expect.
APIs from dart:developer (such as log) are intended to interact with debugging tools:
Interact with developer tools such as the debugger and inspector.
It's not explicit from the documentation for log, but I'd expect it to send a log message only to an attached debugger, not to the console.
If you want logging output that is independent of a debugger, use package:logging and add a listener that calls print, as shown by the example.

where to get the user input in vs code? using dart

I am building a dart program to get the user input. when running the program using the run button I get the output in the output window but I cannot type in it. tried using the terminal to run the program and it worked well. so I want to know what is the right way to take the input from the user?
import 'dart:io';
void main() {
print("enter your name: ");
var name = stdin.readLineSync();
print("hello mrs ${name}");
}
From file -> Preferences -> Settings
search for "Dart: Cli Console"
Dart: Cli Console
Then change the drop-down menu into -terminal-
now you can run again your code and check
you can type in the terminal and your code will work.
In fact the right way using terminal as you did. It's not a fail. It's just how it works.
The answer regarding using the correct vs-code console is correct but you should also check out the dcli package and it's ask function.
Disclaimer: I'm the author of dcli.

Debug DART output not printing

Output display user input integer, instead of Even or Odd
import 'dart:io';
void main() {
print('Enter your number: ');
int n = int.parse(stdin.readLineSync()!);
var result = n % 2 == 0 ? "Even" : "Odd";
print('Your number is : $result');
}
The problem is that your program is running inside the "Debug Console" in VS Code. The following explanation can be found in the Dart settings in VS Code:
The Debug Console has more functionality because the process is controlled by the debug adapter, but is unable to accept input from the user via stdin.
You can change this by going into File -> Preferences -> Settings. Here you go into Extensions -> Dart & Flutter. If you scroll down you can find "Dart: Cli Console". You can also just search for "Dart Cli console":
Instead of "debugConsole" set this to "terminal". Try start your program again and it should now be running inside the "Terminal" tab instead and you should be able to interact with your program and provide data to it though keyboard inputs.

How to record screen while testing in Robot framework Appium?

I'm looking the way how to record screen on Robot framework Appium.I've check on Appium Robot Framework Doc but it doesn't describe about it but i have try to write custom lib with python but it's doesn't support.
import os
import subprocess
from appium import webdriver
from robot.api import logger
desired_caps = {}
desired_caps['platformName'] = 'iOS'
desired_caps['platformVersion'] = '12.3.2'
desired_caps['bundleId'] = 'xxxxxx'
desired_caps['udid'] = 'xxxxxxx'
desired_caps['deviceName'] = 'iPhone'
driver = webdriver.Remote("http://localhost:4723/wd/hub",desired_caps)
def start_screen_recording():
driver.start_recording_screen()
def stop_screen_recording():
filepath = os.path.join("/Users/keo.sidara/Desktop/Mobile_Test/testcases/regression", "screen_recording_110918-205655.mp4")
warning_message(filepath)
payload = driver.stop_recording_screen()
with open(filepath, "wb") as fd:
fd.write(base64.b64decode(payload))
and i got message
[W3C] Matched W3C error code 'invalid session id' to NoSuchDriverError
[W3C (1530275d)] Encountered internal error running command:
NoSuchDriverError:
Anybody experience with it ? please share me. Thanks
The Appium documentation on the start Recording method is here.
In the AppliumLibrary documentation the source code for keyword Open Application shows that the keyword returns number of the application in the registry.
This means that there is no AppiumLibrary supported way of retrieving the webdriver. This means that a modification to the original library is needed. This has been done already in a fork: nichotined / robotframework-appiumlibrary
Removing the original library from your python installation and installing this one, you then have access to the keyword Get Current Application that returns the driver. Now, you can use the below approach or add another keyword yourself in the same fashion to create the custom Start and Stop Screenrecording.
As I don't have a working Appium Setup, I'm unable to validate this myself:
*** Settings ***
Library AppiumLibrary
*** Test Cases ***
Open Application
... http://localhost:4723/wd/hub
... alias=Myapp1
... platformName=iOS
... platformVersion=7.0
... deviceName='iPhone Simulator'
... app=your.app
${driver} Get Current Application
Call Method ${driver} start_recording_screen
As of robotframework-appiumlibrary v1.5.0.6, support for screen recording has been implemented. Can check https://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html#Start%20Screen%20Recording.
Happy Coding!
I've never used Robot Framework before but I tried a lot of ways to record with the appium driver but I couldn't get it working. The only solution that I found was to use ADB SHELL Commands to record the screen of a device. You should have in mind that not all devices are capable of getting their screen recorded.
adb shell screenrecord /sdcard/test.mp4 --size 480x720 #To start recording
Once you kill the process above you can get the video from the device with these commands
adb pull /sdcard/test.mp4 "C:/"
adb shell rm /sdcard/test.mp4

How to run firefox in native app of an extension?

I'm trying simple modify an extension example to run firefox,but I get a message prompt :
Firefox is already running,but is no responding. To open a new new window, you must firest close the existing Firefox process, or restart your system.
#!/usr/bin/env python3
import sys
import json
import struct
import subprocess
try:
# Python 3.x version
# Read a message from stdin and decode it.
def getMessage():
rawLength = sys.stdin.buffer.read(4)
if len(rawLength) == 0:
sys.exit(0)
messageLength = struct.unpack('#I', rawLength)[0]
message = sys.stdin.buffer.read(messageLength).decode('utf-8')
return json.loads(message)
# Encode a message for transmission,
# given its content.
def encodeMessage(messageContent):
encodedContent = json.dumps(messageContent).encode('utf-8')
encodedLength = struct.pack('#I', len(encodedContent))
return {'length': encodedLength, 'content': encodedContent}
# Send an encoded message to stdout
def sendMessage(encodedMessage):
sys.stdout.buffer.write(encodedMessage['length'])
sys.stdout.buffer.write(encodedMessage['content'])
sys.stdout.buffer.flush()
while True:
receivedMessage = getMessage()
if receivedMessage == "ping":
run_result=subprocess.run('firefox -P firefox_word ',shell=True,stdout=subprocess.PIPE)
sendMessage(encodeMessage("pong3"))
except AttributeError:
pass
My purpose is open a local html file by my extension or native app of my extension.
I had a similar issue a while ago, also when I was experimenting with WebExtensions examples. I think the problem is with your Firefox profile. The solution that worked for me was to create a new profile, then (after a day or so) reopen the previous profile. It has been fine since then. I do not know any more details about the problem.
The Mozilla page "Firefox is already running but is not responding" error message - How to fix it describes this solution as well as a number of others (which I tried, but did not have success with).
You can start the Firefox Profile Manager as per the following instructions (see here for complete details):
If Firefox is open, close Firefox:
Press Windows Key + R on the keyboard. A Run dialog will open.
In the Run dialog box, type in: firefox.exe -P Click OK. The Firefox Profile Manager (Choose User Profile) window should open.
Create a new profile, click 'Start Firefox'
To open your previous profile, launch Profile Manager again and select your default profile
For me I need work in same profile,now my solution is made a shell script as daemon to read a fifo and my native app of my extension write that fifo when I need run firefox.
Note you need run that daemon outside the native app of extension.

Resources