How to find source file and line number from os_log() - ios

The Logging Apple reference for the new logging system in iOS 10 and macOS Sierra explicitly say not to include line number and source file info, because it is automatically captured.
Don’t include symbolication information or source file line numbers in messages. The system automatically captures this information.
But I have yet to be able to find any way of viewing these supposedly captured values. In the Console app I can see subsystem, category, process ID, etc, but nothing about file and line.
And the command line tool similarly appears to lack any options for displaying this information (unless I'm missing something).
Anyone figured it out yet?

I don't think it's available in Swift yet, although you can see file and line number in C / C++ in Terminal. See Apple forum here.
I tried something similar to what's inside the forum by creating a simple command-line tool Xcode project:
import Foundation
import os.log
os_log("rrrr")
and type the following in Terminal: log stream --source --predicate 'eventMessage contains "rrrr"', and I got this:
Timestamp Thread Type Activity PID
2017-02-18 17:58:46.012381+0700 0x5067d Default 0x0 5637 <testLogSwift`_swift_os_log> rrrr
in contrast to what I got in C/C++ version, which shows the file and line number:
Timestamp Thread Type Activity PID
2017-02-18 17:55:05.056103+0700 0x4aa01 Default 0x0 5218 <testLogging`main (main.cpp:13)> qqq

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

iOS project - Strange characters in localized strings

The localized strings are loaded with strange characters in my iOS project.
Like instead of "Home" it gets "H̀o̥m̧ë"
I set up 3 .strings files to store the strings used in the project and used swiftgen to generate the enum for using them. (I don't know if this info is relevant, just wanted to give the most comprehensive picture.)
I have my strings like:
"backHomeNavButton" = "Home";
The code that was generated by swiftgen is:
{
…
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
let format = BundleToken.bundle.localizedString(forKey: key, value: nil, table: table)
return String(format: format, locale: Locale.current, arguments: args)
}
…
}
private final class BundleToken {
static let bundle: Bundle = {
Bundle(for: BundleToken.self)
}()
}
The string is already the above mentioned result at let format inside tr(_:_:_:)
Did anyone experienced something similar?
I already tried adding a new .strings file, the results is the same.
I checked it in another project without swiftgen, it worked there. Then I compared those Build Settings that contained Localiz and the projects had the same settings.
I am using Xcode 12.5 at the moment, but when I opened the project in Xcode 12.4 I got the same results.
Thanks for your help in advance.
I figured it out since, so I leave the solution here if anyone gets in the same situation.
You can change the App Language in the Build Scheme. and if you set it to Accented Pseudolanguage, then it will produce these strange characters.

Include file as a string in Dart

In Dart is there a way to include a file as a string, similar to Rust's include_str macro?
I do not want to load the string at runtime from a file or asset.
Not with a similar function.
However there is a workaround that I sometimes use which is a bit different from what you are looking for but might suit your needs :
File translated.dart (presumably generated) :
const translatedHelloWorld = "Hola mundo\n";
In your main file :
import 'translated.dart';
void main() {
assert(translatedHelloWorld, "Hola mundo\n");
}

Logging large strings from Flutter

I'm trying to build a Flutter App and learning Dart in the process, but I'm getting kind of frustrated when debugging. I have fetched a resource from an API and now I want to print the JSON string to the console, but it keeps cutting off the string.
So I actually have two questions: is the terminal console really the only way to print debug messages and how can I print large strings to the console without them automatically getting cut off?
How about using the Flutter log from the dart: developer library. This does not seem to have the maximum length limit like print() or debugPrint(). This is the only solution that seems to work fine. Try it as below:
import 'dart:developer';
log(reallyReallyLongText);
The output will be the entire long string without breaks and prefixed with [log]
You can make your own print. Define this method
void printWrapped(String text) {
final pattern = RegExp('.{1,800}'); // 800 is the size of each chunk
pattern.allMatches(text).forEach((match) => print(match.group(0)));
}
Use it like
printWrapped("Your very long string ...");
Credit
Use debugPrint with the optional parameter to wrap according to the platform's output limit.
debugPrint(someSuperLongString, wrapWidth: 1024);
Currently dart doesn't support printing logs more than 1020 characters (found that out by trying).
So, I came up with this method to print long logs:
static void LogPrint(Object object) async {
int defaultPrintLength = 1020;
if (object == null || object.toString().length <= defaultPrintLength) {
print(object);
} else {
String log = object.toString();
int start = 0;
int endIndex = defaultPrintLength;
int logLength = log.length;
int tmpLogLength = log.length;
while (endIndex < logLength) {
print(log.substring(start, endIndex));
endIndex += defaultPrintLength;
start += defaultPrintLength;
tmpLogLength -= defaultPrintLength;
}
if (tmpLogLength > 0) {
print(log.substring(start, logLength));
}
}
}
There is an open issue for that: https://github.com/flutter/flutter/issues/22665
debugPrint and print are actually truncating the output.
You can achieve this using the Logger Plugin: https://pub.dev/packages/logger
To print any type of log Just do the do the following.
var logger = Logger();
logger.d("Logger is working!");// It also accept json objects
In fact, it will even format the output for you.
Please try debugPrint('your output'); instead of print('your output'); the documentation is here if you would like to read. debugPrint throttles the output to a level to avoid being dropped by android's kernel as per the documentation.
Here is a one-liner based on #CopsOnRoad's answer that you can quickly copy and paste (such as: when you want to slightly modify your code and log some data and see temporarily):
void printWrapped(String text) => RegExp('.{1,800}').allMatches(text).map((m) => m.group(0)).forEach(print);
Method 1
void prints(var s1) {
String s = s1.toString();
debugPrint(" =======> " + s, wrapWidth: 1024);
}
Method 2
void prints(var s1) {
String s = s1.toString();
final pattern = RegExp('.{1,800}');
pattern.allMatches(s).forEach((match) => print(match.group(0)));
}
Just call this method to print your longggg string
If you run the application in android studio it will truncate long string.
In xcode 10.2 which i am using long string is not truncating.
My suggestion is write print statement logs and run the application in Xcode instead of android studio.
Same issue caused lot of frustration when I have to test base64 of images.
I was using iTerm2 editor, so the answer is specific to the iTerm2
1. Navigate to Preferences -> Profiles
2. Select your Profile (in my case was **Default** only)
3. Select **Terminal** in the header of right pan
4. Check Unlimited scrollback
Now you can have copy the large strings from the terminal.

CoreNLP : provide pos tags

I have text that is already tokenized, sentence-split, and POS-tagged.
I would like to use CoreNLP to additionally annotate lemmas (lemma), named entities (ner), contituency and dependency parse (parse), and coreferences (dcoref).
Is there a combination of commandline options and option file specifications that makes this possible from the command line?
According to this question, I can ask the parser to view whitespace as delimiting tokens, and newlines as delimiting sentences by adding this to my properties file:
tokenize.whitespace = true
ssplit.eolonly = true
This works well, so all that remains is to specify to CoreNLP that I would like to provide POS tags too.
When using the Stanford Parser standing alone, it seems to be possible to have it use existing POS tags, but copying that syntax to the invocation of CoreNLP doesn't seem to work. For example, this does not work:
java -cp *:./* -Xmx2g edu.stanford.nlp.pipeline.StanfordCoreNLP -props my-properties-file -outputFormat xml -outputDirectory my-output-dir -sentences newline -tokenized -tagSeparator / -tokenizerFactory edu.stanford.nlp.process.WhitespaceTokenizer -tokenizerMethod newCoreLabelTokenizerFactory -file my-annotated-text.txt
While this question covers programmatic invocation, I'm invoking CoreNLP form the commandline as part of a larger system, so I'm really asking whether this is possible to achieve this with commandline options.
I don't think this is possible with command line options.
If you want you can make a custom annotator and include it in your pipeline you could go that route.
Here is some sample code:
package edu.stanford.nlp.pipeline;
import edu.stanford.nlp.util.logging.Redwood;
import edu.stanford.nlp.ling.*;
import edu.stanford.nlp.util.concurrent.MulticoreWrapper;
import edu.stanford.nlp.util.concurrent.ThreadsafeProcessor;
import java.util.*;
public class ProvidedPOSTaggerAnnotator {
public String tagSeparator;
public ProvidedPOSTaggerAnnotator(String annotatorName, Properties props) {
tagSeparator = props.getProperty(annotatorName + ".tagSeparator", "_");
}
public void annotate(Annotation annotation) {
for (CoreLabel token : annotation.get(CoreAnnotations.TokensAnnotation.class)) {
int tagSeparatorSplitLength = token.word().split(tagSeparator).length;
String posTag = token.word().split(tagSeparator)[tagSeparatorSplitLength-1];
String[] wordParts = Arrays.copyOfRange(token.word().split(tagSeparator), 0, tagSeparatorSplitLength-1);
String tokenString = String.join(tagSeparator, wordParts);
// set the word with the POS tag removed
token.set(CoreAnnotations.TextAnnotation.class, tokenString);
// set the POS
token.set(CoreAnnotations.PartOfSpeechAnnotation.class, posTag);
}
}
}
This should work if you provide your token with POS tokens separated by "_". You can change it with the forcedpos.tagSeparator property.
If you set customAnnotator.forcedpos = edu.stanford.nlp.pipeline.ProvidedPOSTaggerAnnotator
to the property file, include the above class in your CLASSPATH, and then include "forcedpos" in your list of annotators after "tokenize", you should be able to pass in your own pos tags.
I may clean this up some more and actually include it in future releases for people!
I have not had time to actually test this code out, if you try it out and find errors please let me know and I'll fix it!

How do I print to the console with Dart?

I'd like my Dart program to print to the dev console of my browser. How can I print to the console (DevTools's console, for example) ?
Use print() to print a string to the console of your browser:
import 'dart:html';
main() {
var value = querySelector('input').value;
print('The value of the input is: $value');
}
You will see a message printed to the developer console.
If you simlpy want to print text to the console you can use print('Text').
But if you want to access the advanced fatures of the DevTools console you need to use the Console class from dart:html: Console.log('Text').
It supports printing on different levels (info, warn, error, debug). It also allows to print tables and other more advanced features. Note that these are not supported in every browser! It's sad that the documentation about the Console class is incomplete, but you can take a look at the documentation of Chrome here and here.
There is log() from import 'dart:developer' library also.
example:
int name = "Something";
log("ClassName: successfully initialized: $name");
//output
[log] ClassName: successfully initialized: Something
Please note that log and debugPrint taking a value of String not like print. So, you have to add .toString() at the end or use with String interpolation like I used in above example.
From doc:
You have two options for logging for your application. The first is to
use stdout and stderr. Generally, this is done using print()
statements, or by importing dart:io and invoking methods on stderr and
stdout. For example:
stderr.writeln('print me');
If you output too much at once, then Android sometimes discards some
log lines. To avoid this, use debugPrint(), from Flutter’s foundation
library. This is a wrapper around print that throttles the output to a
level that avoids being dropped by Android’s kernel.
The other option for application logging is to use the dart:developer
log() function. This allows you to include a bit more granularity and
information in the logging output. Here’s an example:
import 'dart:developer' as developer;
void main() {
developer.log('log me', name: 'my.app.category');
developer.log('log me 1', name: 'my.other.category');
developer.log('log me 2', name: 'my.other.category');
}
You can also pass application data to the log call. The convention for
this is to use the error: named parameter on the log() call, JSON
encode the object you want to send, and pass the encoded string to the
error parameter.
import 'dart:convert'; import 'dart:developer' as developer;
void main() {
var myCustomObject = ...;
developer.log(
'log me',
name: 'my.app.category',
error: jsonEncode(myCustomObject),
);
}
If viewing the logging output in DevTool’s logging view, the JSON
encoded error param is interpreted as a data object and rendered in
the details view for that log entry.
read more(It's cool like a tutorial).
If you are here for Flutter, there's debugPrint which you should use.
Here's the doc text for the same.
/// Prints a message to the console, which you can access using the "flutter"
/// tool's "logs" command ("flutter logs").
/// By default, this function very crudely attempts to throttle the rate at
/// which messages are sent to avoid data loss on Android. This means that
/// interleaving calls to this function (directly or indirectly via, e.g.,
/// [debugDumpRenderTree] or [debugDumpApp]) and to the Dart [print] method can
/// result in out-of-order messages in the logs.
You might get SDK version constraint as it is only for 2.2 and above.
Dart print() function works differently in different environment.
print() when used in console based application it outputs in the terminal console
print() when used in web based application it outputs to the developer console.
void main() {
print("HTML WebApp");
}
The only way I know , which is supported by dartpad ,is through using print();
by the way Dart uses the ${} syntax for expressions, or just a $ for single value.
ex:-
int x=3;
print('hello world') ;
print(x) ;
print('x = $x') ;
and her is the link for the documentation
print method!

Resources