I have enabled the nativeOptions: {capture: true} in initOptions.js
logger : {enabled: true, level: 'debug', stringify: true, pretty: false,
tag: {level: false, pkg: true}, whitelist: [], blacklist: [], nativeOptions: {capture: true}}
In my main js file i have the following code.
function wlCommonInit(){
// Common initialization code goes here
WL.Logger.setNativeOptions({'capture': true});
var logger = WL.Logger.create({pkg: 'mypackage'});
logger.debug('Hello world - debug');
//[mypackage] Hello world
logger.log('Hello world - log');
//[mypackage] Hello world
logger.info('Hello world - info');
//[mypackage] Hello world
logger.warn('Hello world - warn');
//[mypackage] Hello world
logger.error('Hello world - error');
//[mypackage] Hello world
WL.Logger.send(); }
WL.Logger.send() suppose to call my adapter "WLClientLogReceiver". But i am not getting any call for this adapter.
Please let me know, i need to enable any other settings to upload my client side captured log to server.
function log(deviceInfo, logMessages) {
return true;}
<procedure name="log" securityTest="wl_unprotected" audit="true" />
logger : {enabled: true, level: 'debug', stringify: true, pretty: false, tag: {level: false, pkg: true}, whitelist: [], blacklist: [], nativeOptions: {capture: true}}
You have enabled the native capture as true in initOptions.js so no need to set it again.
You can log using your package that will help you in filtering the messages based on the package in your WLClientLogReceiver adapter.
var myloggerObject = WL.Logger.create({pkg: 'mypackage'});
myloggerObject.debug("Hello world");
you can specify your level in your js file to be logged in client device.
In the adapter you will get the log messages as an json array.
function log(deviceInfo, logMessages) {
/* The adapter can choose to process the parameters,
for example to forward them to a backend server for
safekeeping and further analysis.
The deviceInfo object may look like this:
{
"appName": "wlapp",
"appVersion": "1.0",
"deviceId": "66eed0c9-ecf7-355f-914a-3cedac70ebcc",
"model": "Galaxy Nexus - 4.2.2 - API 17 - 720x1280",
"systemName": "Android",
"systemVersion": "4.2.2",
"os.arch": "i686", // Android only
"os.version": "3.4.0-qemu+" // Android only
}
The logMessages parameter is a JSON array
that contains JSON object elements, and might look like this:
[{
"timestamp" : "17-02-2013 13:54:23:745", // "dd-MM-yyyy hh:mm:ss:S"
"level" : "ERROR", // ERROR||WARN||INFO||LOG|| DEBUG
"package" : "your_tag", // typically a class name
"msg" : "the message", // a helpful log message
"threadid" : 42, // (Android only)the current thread
"metadata" : { "$src" : "js" } // metadata placed on the log call
}]
*/
//sample log and filtering method
var logs= [{
"timestamp" : "17-02-2013 13:54:23:745", // "dd-MM-yyyy hh:mm:ss:S"
"level" : "ERROR", // ERROR||WARN||INFO||LOG|| DEBUG
"package" : "your_tag", // typically a class name
"msg" : "the message", // a helpful log message
"threadid" : 42, // (Android only)the current thread
"metadata" : { "$src" : "js" } // metadata placed on the log call
},
{
"timestamp" : "17-02-2013 13:54:23:745", // "dd-MM-yyyy hh:mm:ss:S"
"level" : "ERROR", // ERROR||WARN||INFO||LOG|| DEBUG
"package" : "mypackage", // typically a class name
"msg" : "my package message", // a helpful log message
"threadid" : 42, // (Android only)the current thread
"metadata" : { "$src" : "js" } // metadata placed on the log call
}
];
var filteredLogs = logs.filter(function(log){
if(log.package == mypackage) //comparing the package and returns the object
{ return log; }
});
WL.Logger.error(filteredLogs);// This is send only the filtered array to your server
}
If you log using metadata such as filename along with the debug message you will get those in the array in metadata attribute.
It is suggested to stringify and parse the object to avoid errors before parsing the device logs in the adapter.
var logs = JSON.stringify(JSON.parse(logs));
var filteredLogs = logs.filter ...
Hope this will work for you.
Make sure you test it using the device.
The send function is not attached to the LogInstance prototype, which is what you're using when you use a logger instance created with WL.Logger.create(). Please call
WL.Logger.send();
instead.
(Above was posted prior to OP's edit.)
Since setNativeOptions is an asynchronous call (it calls down through a Cordova plugin), it is possible it has not successfully turned capture on prior to completion of the subsequent logger calls. So at the time of the call to WL.Logger.send(); nothing has been collected yet.
Do this:
function wlCommonInit() {
// Common initialization code goes here
WL.Logger.setNativeOptions({'capture': true})
.then(function() {
var logger = WL.Logger.create({pkg: 'mypackage'});
logger.debug('Hello world - debug');
//[mypackage] Hello world
logger.log('Hello world - log');
//[mypackage] Hello world
logger.info('Hello world - info');
//[mypackage] Hello world
logger.warn('Hello world - warn');
//[mypackage] Hello world
logger.error('Hello world - error');
//[mypackage] Hello world
WL.Logger.send();
});
}
Be sure to check the server-side logs. The audit="true" in the adapter's descriptor file will print the parameters passed to the adapter inline in the server logs (messages.log on WebSphere Liberty).
Related
I'm a server side developer with rudimentary JS knowhow. I'm tinkering with Agora's audio broadcasting functionality (specifically for the web). For reference, I've been following this: https://docs.agora.io/en/Audio%20Broadcast/start_live_audio_web?platform=Web
I'm attempting to broadcast audio as a host. I have an HTML button which fires a JS function where I:
Initialize a client
Set the role
Join a predefined channel
Publish a local stream
My understanding is that accomplshing the aforementioned will enable me to broadcast audio. When I try this, I end up getting a client join failed DYNAMIC_KEY_EXPIRED error. I'm unable to find documentation regarding how to resolve this. Can you help me resolve this? An illustrative example would be nice.
My JS code is below. Note that I'm using a temp token to test this functionality on localhost.
// rtc object
var rtc = {
client: null,
joined: false,
published: false,
localStream: null,
remoteStreams: [],
params: {}
};
// Options for joining a channel
var option = {
appID: "anAppID",// from 'Project Management' dashboard
channel: "AudioLive",
uid: null,//The user ID should be unique in a channel. If you set the user ID as null or 0, the Agora server assigns a user ID and returns it in the onSuccess callback.
token: "aTempToken"// TEMP Token
}
function createBroadcast(role) {
console.log("entered createBroadcast");
// Create a client
rtc.client = AgoraRTC.createClient({mode: "live", codec: "h264"});
// Initialize the client
rtc.client.init(option.appID, function () {
console.log("init success");
// Note: in a live broadcast, only the host can be heard and seen. You can also call setClientRole() to change the user role after joining a channel.
rtc.client.setClientRole(role);
console.log("role is set");
// Call Client.join in the onSuccess callback of Client.init
rtc.client.join(option.token ? option.token : null, option.channel, option.uid ? +option.uid : null, function (uid) {
console.log("join channel: " + option.channel + " success, uid: " + uid);
rtc.params.uid = uid;
// Call AgoraRTC.createStream to create a stream in the onSuccess callback of Client.join
rtc.localStream = AgoraRTC.createStream({
streamID: rtc.params.uid,
audio: true,
video: false,
screen: false,
})
// Call Stream.init to initialize the stream after 'creating' the stream above
// Initialize the local stream
rtc.localStream.init(function () {
console.log("init local stream success");
// play stream with html element id "local_stream"
rtc.localStream.play("local_stream");
// Call Client.publish in the onSuccess callback of Stream.init to publish the local stream
// Publish the local stream
rtc.client.publish(rtc.localStream, function (err) {
console.log("publish failed");
console.error(err);
})
}, function (err) {
console.error("init local stream failed ", err);
});
}, function(err) {
console.error("client join failed", err)
})
}, (err) => {
console.error(err);
});
}
<div style="background:#f0f3f4;padding:20px">
<button id="broadast" style="height:40px;width:200px" onclick="createBroadcast('host')">Start Live Broadcast</button>
</div>
I've not added the actual values for appID and token in the code above.
Note: Please ask for more information in case you require it.
The error that you are facing is due to the expiry of the token generated for authentication purposes while generating an APP ID. To resolve this you will have to generate a new token as elaborated in the below given links:
Token-expired
renewToken
A token (or a temporary token) expires after a certain period of time. When the SDK notifies the client that the token is about to expire or has expired by the onTokenPrivilegeWillExpire or onTokenPrivilegeDidExpire callbacks, you need to generate a new token and call the renewToken method.
client.on("onTokenPrivilegeWillExpire", function(){
//After requesting a new token
client.renewToken(token);
});
client.on("onTokenPrivilegeDidExpire", function(){
//After requesting a new token
client.renewToken(token);
});
Include the above functions in your javascript code along with the rest of the eventListeners.
Incase your application doesn't require security you can opt to not use a token and generate an App ID without a certificate.
App ID without certificate
Do get back for further support incase the issue remains unresolved.
Below sample code is not working in latest fix on Android but if we remove the password field from options then it's working fine. We are getting below error on Android but it's working fine on IOS
{"src":"initCollection","err":-3,"msg":"INVALID_KEY_ON_PROVISION","col":"people","usr":"test","doc":{},"res":{}}
function wlCommonInit(){
/*
* Use of WL.Client.connect() API before any connectivity to a MobileFirst Server is required.
* This API should be called only once, before any other WL.Client methods that communicate with the MobileFirst Server.
* Don't forget to specify and implement onSuccess and onFailure callback functions for WL.Client.connect(), e.g:
*
* WL.Client.connect({
* onSuccess: onConnectSuccess,
* onFailure: onConnectFailure
* });
*
*/
// Common initialization code goes here
}
function onClick(){
alert("Click");
var collectionName = 'people';
// Object that defines all the collections.
var collections = {
// Object that defines the 'people' collection.
people : {
// Object that defines the Search Fields for the 'people' collection.
searchFields : {name: 'string', age: 'integer'}
}
};
// Optional options object.
var options = {
username:"test",
// Optional password, default no passw`enter code here`ord.
password : '123',
};
WL.JSONStore.init(collections, options)
.then(function () {
alert("Success in jstore");
})
.fail(function (errorObject) {
// Handle failure for any of the previous JSONStore operations (init, add).
alert("Failure in jstore : "+ JSON.stringify(errorObject));
});
};
Update: The iFix is now released. Build number is 7.1.0.0-IF201610060540 .
This is a known issue with the latest available iFix. It has been recently fixed and should be available soon.
Keep an eye out for a newer iFix release in the IBM Fix Central website for a fix for this issue.
I have the misfortune of further developing an existing mobile application in Appcelerator. The app uses a Rest API on a remote server to read and write data. The API works well in test environments and in production. I need to post data to the API and read the output. Here is an example of what the output of the API looks like after a POST command:
{
"equipment":
{
"result": "create",
"id": 419213
},
"_meta":
{
"offset": 0,
"limit": -1,
"total_results": 1,
"url": "http://localhost:8080/api/v1/equipment",
"utc_start_time": 1459449461115,
"nano_total_time": 74771
}
}
I am able to successfully post the data in Appcelerator. I have verified this in the database that the CRUD operation is acting on. However, I am unable to get the aforementioned data from the httpClient object that makes the call, despite following the directions in the outdated Titanium documentation.
Here is my Appcelerator code:
var payload = "name=atad&asset_number=adtasd&department_id=185080&property_id=10086&designator_id=379828&is_leased=N&is_assignable_asset=N&status=A";
var url = "http://localhost:8080/api/v1/equipment";
var client = Ti.Network.createHTTPClient({
onload : function(e) {
Ti.API.info(e); // {}
Ti.API.info(e.source); // []
Ti.API.info(JSON.stringify(e.source)); // {}
Ti.API.info(JSON.stringify(e.source.reponseText)); // null
Ti.API.info(JSON.stringify(e.source.reponseData)); // null
Ti.API.info(this); // []
console.log(JSON.stringify(this)); // {}
Ti.API.info(JSON.stringify(this.reponseText)); // null
Ti.API.info(this.reponseData); // null
}
,onerror : function(e){
Ti.API.info(e);
alert("error");
}
});
var auth = 'Basic ' + Ti.App.Properties.getString('auth');
client.open("POST", apiUrl);
client.setRequestHeader('Authorization', auth);
client.setRequestHeader('Content-Type', 'text/plain');
client.send(payload);
Here is the console output:
[INFO] : {
[INFO] : code = 0;
[INFO] : source = "[object TiNetworkHTTPClient]";
[INFO] : success = 1;
[INFO] : type = load;
[INFO] : }
[INFO] : [object TiNetworkHTTPClient]
[INFO] : {"method":"POST","url":"http://localhost:8080/api/v1/equipment"}
[INFO] : <null>
[INFO] : <null>
[INFO] : [object TiNetworkHTTPClient]
[INFO] : {"method":"POST","url":"http://localhost:8080/api/v1/equipment"}
[INFO] : <null>
[INFO] : <null>
The documentation here http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Network.HTTPClient explicitly says to use this.responseText, but that is clearly not giving me the results I need. I need that "id" that is being returned from the server.
How do I read the data that is returned from the server after a post API call?
There is just a typo in this.responseText
Have a look at this module: https://github.com/jasonkneen/RESTe
It makes your life easier and gives you a great way to the same syntax for future projects!
If you want to keep your syntax (which is fine too):
have a look at this example: https://github.com/m1ga/titanium-libraries/blob/master/api.js#L49
and the following lines. It shows you how to read the JSON. Basically you have to wait for if (this.readyState === 4) {} inside the onload and then read the this.responseText or JSON.parse() it.
It looks like the apiUrl variable is not defined?
Which could explain a lot or your current frustration.
This is what i a getting on my Corona Simulator Output when i try to install the 'playhaven' plugin. I don't know how to get rid of this.
Build: 2013.1202 Runtime error ?:0: attempt to call field 'request' (a nil value) stack traceback:
[C]: in function 'request'
?: in function 'downloadManifest'
?: in function 'downloadQueuedManifests'
?: in function <?:632>
?: in main chunkRuntime error
stack traceback:
[C]: in function 'request'
?: in function 'downloadManifest'
?: in function 'downloadQueuedManifests'
?: in function <?:632>
?: in main chunk
In case you wanna take a look at my build.settings file because after i integrated the plugins into the build.settings file. I recieved the error i showed above.
settings =
{
orientation =
{
default = "portrait",
supported = { "portrait" },
},
androidPermissions =
{
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.INTERNET",
"android.permission.READ_PHONE_STATE",
"android.permission.ACCESS_NETWORK_STATE",
},
plugins =
{
-- key is the name passed to Lua's 'require()'
["plugin.playhaven"] =
{
-- required
publisherId = "com.playhaven",
},
},
iphone =
{
plist =
{
UIPrerenderedIcon = true,
UIApplicationExitsOnSuspend = false,
CFBundleIconFile = "Icon.png",
CFBundleIconFiles = {
"Icon.png",
"Icon#2x.png",
},
},
},
}
Playhaven is only available to Pro and Enterprise subscribers. See:
http://docs.coronalabs.com/daily/plugin/playhaven/
Are you a Pro or a Starter?
Since you gave so few information on your system and environment I can only guess. It seems that the installer tried to download something (or connect via some protocol) and failed. Did you check your firewall/proxy settings? Maybe connections are automatically refused and you are not aware of it.
Is there a way to output the json-string read by my store in sencha touch 2?
My store is not reading the records so I'm trying to see where went wrong.
My store is defined as follows:
Ext.define("NotesApp.store.Online", {
extend: "Ext.data.Store",
config: {
model: 'NotesApp.model.Note',
storeId: 'Online',
proxy: {
type: 'jsonp',
url: 'http://xxxxxx.com/qa.php',
reader: {
type: 'json',
rootProperty: 'results'
}
},
autoLoad: false,
listeners: {
load: function() {
console.log("updating");
// Clear proxy from offline store
Ext.getStore('Notes').getProxy().clear();
console.log("updating1");
// Loop through records and fill the offline store
this.each(function(record) {
console.log("updating2");
Ext.getStore('Notes').add(record.data);
});
// Sync the offline store
Ext.getStore('Notes').sync();
console.log("updating3");
// Remove data from online store
this.removeAll();
console.log("updated");
}
},
fields: [
{
name: 'id'
},
{
name: 'dateCreated'
},
{
name: 'question'
},
{
name: 'answer'
},
{
name: 'type'
},
{
name: 'author'
}
]
}
});
you may get all the data returned by the server through the proxy, like this:
store.getProxy().getReader().rawData
You can get all the data (javascript objects) returned by the server through the proxy as lasaro suggests:
store.getProxy().getReader().rawData
To get the JSON string of the raw data (the reader should be a JSON reader) you can do:
Ext.encode(store.getProxy().getReader().rawData)
//or if you don't like 'shorthands':
Ext.JSON.encode(store.getProxy().getReader().rawData)
You can also get it by handling the store load event:
// add this in the store config
listeners: {
load: function(store, records, successful, operation, eOpts) {
operation.getResponse().responseText
}
}
As far as I know, there's no way to explicitly observe your response results if you are using a configured proxy (It's obviously easy if you manually send a Ext.Ajax.request or Ext.JsonP.request).
However, you can still watch your results from your browser's developer tools.
For Google Chrome:
When you start your application and assume that your request is completed. Switch to Network tab. The hightlighted link on the left-side panel is the API url from which I fetched data. And on the right panel, choose Response. The response result will appear there. If you have nothing, it's likely that you've triggered a bad request.
Hope this helps.
Your response json should be in following format in Ajax request
{results:[{"id":"1", "name":"note 1"},{"id":"2", "name":"note 2"},{"id":"3", "name":"note 3"}]}
id and name are properties of your model NOte.
For jsonp,
in your server side, get value from 'callback'. that value contains a name of callback method. Then concat that method name to your result string and write the response.
Then the json string should be in following format
callbackmethod({results:[{"id":"1", "name":"note 1"},{"id":"2", "name":"note 2"},{"id":"3", "name":"note 3"}]});