I'm in the process of migrating some Sharepoint sites from one farm to another farm. It's a little more complicated, but for simplicity sake...
What I'd like to maintain is old URLs that people have for these sites, documents, etc. and the IIS URL Rewrite Module seems like a good way to go.
Here's an idea of what the structure is:
_______________________ _______________________
|oldfarm.company.com**| |newfarm.company.com**|
|oldsitecollection** | |newsitecollection** |
|subsitename | |subsitename |
|... | |... |
|_____________________| |_____________________|
** = changes, everything else remains the same, URLwise.
On the "newfarm" I have extended the web application to respond to "oldfarm.company.com", and that web application has a URL Redirect Rule that redirects http://oldfarm.company.com/oldsitecollection/... to http://newfarm.company.com/newsitecollection/...
That works great for the vast majority of what I'm trying to do.
What I'm having difficulty with is rewriting QUERYSTRING values. Sharepoint's Office Document Viewers contain path information in the QUERYSTRING and that's what I need to change.
Here is an original URL sample:
http://oldfarm.company.com/oldsitecollection/subsitename/_layouts/WordViewer.aspx?id=/oldsitecollection/subsitename/doclib/doc.docx&Source=http%3A%2F%2Foldfarm%2Ecompany%2Ecom%2Foldsitecollection%2Fsubsitename%2Fdoclib%2FForms%2FAllItems%2Easpx&DefaultItemOpen=1
Here is the URL after the redirect (and where I'm stuck):
http://newfarm.company.com/newsitecollection/subsitename/_layouts/WordViewer.aspx?id=/oldsitecollection/subsitename/doclib/doc.docx&Source=http%3A%2F%2Foldfarm%2Ecompany%2Ecom%2Foldsitecollection%2Fsubsitename%2Fdoclib%2FForms%2FAllItems%2Easpx&DefaultItemOpen=1
Here is what I need the URL to look like:
http://newfarm.company.com/newsitecollection/subsitename/_layouts/WordViewer.aspx?id=/newsitecollection/subsitename/doclib/doc.docx&Source=http%3A%2F%2Fnewfarm%2Ecompany%2Ecom%2Fnewsitecollection%2Fsubsitename%2Fdoclib%2FForms%2FAllItems%2Easpx&DefaultItemOpen=1
I have tried using Rewrite Maps because these are not dynamic substitutions, but I cannot get them to modify the QUERYSTRING.
Here's an example of the rewrite rule I'm working on:
<rewrite>
<rewriteMaps>
<rewriteMap name="WordViewer">
<add key="id=/oldsitecollection" value="id=/newsitecollection" />
</rewriteMap>
</rewriteMaps>
<rules>
<rule name="Rewrite rule1 for WordViewer">
<match url=".*WordViewer.aspx" />
<conditions>
<add input="{WordViewer:{QUERY_STRING}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
To answer my own question, what worked for me was to create my own custom rewrite provider.
The provider I created was a simple find/replace provider that looked like this:
public class FindReplaceProvider : IRewriteProvider, IProviderDescriptor
{
public string Find { get; private set; }
public string Replace { get; private set; }
public void Initialize(IDictionary<string, string> settings, IRewriteContext rewriteContext)
{
string tmpFind, tmpReplace;
if (!settings.TryGetValue("Find", out tmpFind) || string.IsNullOrEmpty(tmpFind))
throw new ArgumentException("FindReplaceProvider setting 'Find' is required and cannot be empty");
if (!settings.TryGetValue("Replace", out tmpReplace))
throw new ArgumentException("FindReplaceProvider setting 'Replace' is required and cannot be null");
if (!string.IsNullOrEmpty(tmpFind))
Find = tmpFind;
else
throw new ArgumentException("FindReplaceProvider parameter 'Find' cannot be empty");
if (!string.IsNullOrEmpty(tmpReplace))
Replace = tmpReplace;
else
Replace = String.Empty;
}
public string Rewrite(string value)
{
return Regex.Replace(value, Find, Replace, RegexOptions.IgnoreCase);
}
public IEnumerable<SettingDescriptor> GetSettings()
{
yield return new SettingDescriptor("Find", "String to find");
yield return new SettingDescriptor("Replace", "String to replace");
}
}
And my rewrite rules end up looking like this:
<rewrite>
<providers>
<provider name="OfficeWebAppsReplaceId" type="MyFindReplaceProvider">
<settings>
<add key="Find" value="id=/oldsitecollection" />
<add key="Replace" value="id=/newsitecollection" />
</settings>
</provider>
<provider name="OfficeWebAppsReplaceSource" type="MyFindReplaceProvider">
<settings>
<add key="Find" value="http%3A%2F%2Foldfarm%2Ecompany%2Ecom%2Foldsitecollection%2" />
<add key="Replace" value="http%3A%2F%2Fnewfarm%2Ecompany%2Ecom%2Fnewsitecollection%2" />
</settings>
</provider>
</providers>
<rules>
<rule name="OfficeWebAppsQuerystringRedirect" stopProcessing="true">
<match url=".*(WordViewer.aspx|WordEditor.aspx|xlviewer.aspx|PowerPoint.aspx)$" />
<conditions logicalGrouping="MatchAny">
<add input="{QUERY_STRING}" pattern=".*id=/oldsitecollection.+" />
<add input="{QUERY_STRING}" pattern=".*Source=http%3A%2F%2Foldfarm%2Ecompany%2Ecom%2Foldsitecollection%2F.+" />
</conditions>
<action type="Redirect" url="{R:0}?{OfficeWebAppsReplaceId:{OfficeWebAppsReplaceSource:{C:0}}}" appendQueryString="false" redirectType="Temporary" />
</rule>
</rules>
</rewrite>
Related
I was trying to save an image in a gallery via an app.
this is the error I got
java.lang.IllegalArgumentException: Couldn't find meta-data for a provider with authority com.example.android.fileprovider
I have a button which would capture an image from the camera by calling the below function.
**Code for saving the image **
val REQUEST_TAKE_PHOTO = 1
private fun dispatchTakePictureIntent() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
// Ensure that there's a camera activity to handle the intent
takePictureIntent.resolveActivity(packageManager)?.also {
// Create the File where the photo should go
val photoFile: File? = try {
createImageFile()
} catch (ex: IOException) {
// Error occurred while creating the File
Log.i("Exception","${ex.toString()}")
null
}
// Continue only if the File was successfully created
photoFile?.also {
val photoURI: Uri = FileProvider.getUriForFile(
this,
"com.example.android.fileprovider",
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
}
}
}
}
lateinit var currentPhotoPath: String
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = absolutePath
}
}
Now I in google docs I found out that we need to add some more lines in Manifest.xml file, so I added them, but still, there is an error
<?XML version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.intentexperiment">
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SET_ALARM" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
android:name="image" android:path="Android/data/com.example.package.name/files/Pictures" />
</paths>
I don't understand where the error is.
EDIT
I have moved the
<path>
...
</path>
in an XML file and accordingly changed the android: resource attribute
but the error now is
java.lang.RuntimeException: Unable to get provider android.support.v4.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.FileProvider" on path: DexPathList[[zip file "/data/app/com.example.intentexperiment-l0jZknwE-m3bgGza6RJAug==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.intentexperiment-l0jZknwE-m3bgGza6RJAug==/lib/arm64, /system/lib64]]
EDIT 2
after doing this
android:name="androidx.core.content.FileProvider"
still there is a error
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.intentexperiment/files/Pictures/JPEG_20200425_194311_3114424866623330911.jpg
at androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:744)
at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:418)
at com.example.intentexperiment.MainActivity.dispatchTakePictureIntent(MainActivity.kt:54)
at com.example.intentexperiment.MainActivity.access$dispatchTakePictureIntent(MainActivity.kt:22)
at com.example.intentexperiment.MainActivity$onCreate$1.onClick(MainActivity.kt:31)
at android.view.View.performClick(View.java:6600)
at android.view.View.performClickInternal(View.java:6577)
at android.view.View.access$3100(View.java:781)
at android.view.View$PerformClick.run(View.java:25912)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6923)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:870)
I have a simple bit of code on my classic ASP website to send me an email when a page errors, as I have this set up in my web.config to point at a page to handle errors:
<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
<remove statusCode="500" subStatusCode="100" />
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/error_404.asp" responseMode="ExecuteURL" />
<error statusCode="500" prefixLanguageFilePath="" path="/error_500.asp" responseMode="ExecuteURL" />
<error statusCode="500" subStatusCode="100" path="/error_500.asp" responseMode="ExecuteURL" />
</httpErrors>
This is my simple bit of code:
...
set objError = Server.getLastError()
strNumber = objError.AspCode
strSource = objError.Category
strDesc = newstr(objError.Description)
strCode = newstr(objError.Source)
strLine = ObjError.Line
strASPDesc = ObjError.ASPDescription
strRemoteAddr = Request.ServerVariables("REMOTE_ADDR")
ref = request.servervariables("HTTP_REFERER")
str = request.servervariables("QUERY_STRING")
cookies = request.servervariables("HTTP_COOKIE")
ip_url = strRemoteAddr
ua = newstr(request.servervariables("HTTP_USER_AGENT"))
totalstring = objError.File & "?" & str
I then concatenate those values together and email the details to myself.
For an error, I'd get something like this:
strNumber: ASP 0126
strSource: Active Server Pages
strDesc: Include file not found
strCode:
strLine: 14
strASPDesc: The include file '/news/aw.asp' was not found.
strRemoteAddr: 2.101.166.175
ref: http://example.com/sites/support/
str: page=cd
cookies: usr1=62105233D8E2A062A55; fantastic%5Fcheese=1; _ga=GA1.3.1357551757.1476543431; __atuvc=2%7C41%2C1%7C42%2C0%7C43%2C0%7C44%2C9%7C45; __utma=154830755.1357551757.1476543431.1476822981.1479368067.3; __utmz=154830755.1476818175.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ASPSESSIONIDQCBABQAR=KHGBAMBCCCENHCIPPCOFBJOO; __utmb=154830755.1.10.1479368067; __utmc=154830755; __utmt=1
ip_url: 84.92.46.118
ua: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
totalstring: /sites/support/page.asp?landscape=cd
However, I often only see this error:
strNumber:
strSource:
strDesc:
strCode:
strLine: 0
strASPDesc:
strRemoteAddr: 43.247.156.6
ref: http:/example.com/content/this.asp
str: 500;http://jimpix.co.uk:80/words/check-username.asp
cookies: ASPSESSIONIDSAABARBQ=ACDDOHOCEKIEFOCKFBFIHJBC; _gat=1; __atuvc=129%7C46; __atuvs=582e898682f62926059; _ga=GA1.3.491207786.1479439414
ip_url: 43.247.156.6
ua: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
totalstring: ?500;http:/example.com:80/content/this.asp
There are no error details as such, but it's always on the same page. I can't work out what's causing it.
Is there any more detailed error logging I can do to find out more?
Server.getLastError() only remains populated until the response buffer has started to flush content to the client, reasons for this could be:
response.buffer is set to false
response.flush has been called
response.end has been called
There is a reference to this in the documentation:
This method is available only before the .asp file has sent any
content to the client.
This is the only thing i can think of that would explain why your Server.getLastError() seems to be blank.
While it works perfectly when run locally through VS Studio's included IIS Express, my application chokes once deployed to IIS 8:
System.Web.HttpException: Could not load type 'Nancy.Hosting.Aspnet.NancyHttpRequestHandler'.
Back-end is MS Owin, written in VB (.NET 4.5), which registers 3 middlewares: OAuth server, JWT bearer Authentication, and Nancy. Front end is AngularJS. The proper DLLs are included in the published directory.
IIS 8 has .NET 4.5 installed and enabled. It is running in integrated mode.
I am not sure if this is related to the configuration of Nancy within web.config or the configuration of IIS. Relevant source follows:
Startup.vb
Public Sub Configuration(app As IAppBuilder)
Dim issuer As String = "http://obscured-domain"
Dim audience As String = "obscured-audience-key"
Dim secret As Byte() = Microsoft.Owin.Security.DataHandler.Encoder.TextEncodings.Base64Url.Decode("obscured-client-secret")
'CORS Configuration
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
app.UseOAuthAuthorizationServer(New OAuthAuthorizationServerOptions() With { _
.AllowInsecureHttp = True, _
.TokenEndpointPath = New PathString("/authenticate"), _
.AccessTokenExpireTimeSpan = TimeSpan.FromHours(1), _
.AccessTokenFormat = New JwtFormat(issuer, audience), _
.Provider = New OAuthServerProvider()
})
app.UseJwtBearerAuthentication(New JwtBearerAuthenticationOptions() With { _
.AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, _
.AllowedAudiences = New String() {audience}, _
.IssuerSecurityTokenProviders = New IIssuerSecurityTokenProvider() { _
New SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
}
})
'Content service
Dim nOpts As New NancyOptions
nOpts.PassThroughWhenStatusCodesAre(HttpStatusCode.NotFound, HttpStatusCode.InternalServerError)
app.UseNancy(nOpts)
'Handle IIS request pipeline staging
app.UseStageMarker(PipelineStage.MapHandler)
End Sub
Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</httpHandlers>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
</handlers>
</system.webServer>
<connectionStrings>
<add name="FTConnStr" connectionString="obscured-connection-string" />
</connectionStrings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Example Nancy Module
Public Class KnowledgeBaseModule
Inherits NancyModule
'Get page of article briefs via full-text search
MyBase.Get("/api/articles/paged/{offset}/{numRows}") = _
Function(parameters)
Dim searchFields As FullTextFields = Me.Bind(Of FullTextFields)()
Try
Dim results As Dictionary(Of String, List(Of Dictionary(Of String, Object)))
results = FullTextProvider.pagedSearch(searchFields.fields("SearchString"), CInt(parameters.offset), CInt(parameters.numRows))
Return Response.AsJson(results)
Catch ex As Exception
'temp 500
Return HttpStatusCode.InternalServerError
End Try
End Function
Private Class FullTextFields
Public Property fields As Dictionary(Of String, String) = New Dictionary(Of String, String) From _
{
{"SearchString", String.Empty}
}
End Class
End Class
Since you're using OWIN you need to use the SystemWeb host not Nancy's AspNet host. You also need to remove these two parts from your web.config:
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</httpHandlers>
<handlers>
<add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
</handlers>
You probably have a copy of the nancy host in your bin folder which is why it works locally but not when you deploy it.
I have a problem when i use nlog for error and logging. Here is my code :
Error : Error when setting property 'Layout' on File Target[file]
Nlog.config
<target name="file" xsi:type="File" layout="${date}|${level}|${logger}|${steps_guid}|${machinename}|${windows-identity:domain=false}--${message} ${exception:format=message,stacktrace:separator=*" fileName="E:\myapplication.log" />
<target xsi:type="Database" name="database" connectionString="Data Source=xxx;Initial Catalog=xxx;Integrated Security=True" commandText="exec [dbo].[LOGINNG_CREATE] #steps_guid,#log_application ,#log_date,#log_level ,#log_logger , #log_message ,#log_machine_name , #log_user_name ,#log_call_site ,#log_thread ,#log_exception , #log_stacktrace ">
<parameter name="#steps_guid" layout="${steps_guid}"/>
<parameter name="#log_application" layout="${application}"/>
<parameter name="#log_date" layout="${date}"/>
<parameter name="#log_level" layout="${level}"/>
<parameter name="#log_logger" layout="${logger}"/>
<parameter name="#log_message" layout="${message}"/>
<parameter name="#log_machine_name" layout="${machinename}"/>
<parameter name="#log_user_name" layout="${windows-identity:domain=true}"/>
<parameter name="#log_call_site" layout="${callsite:filename=true}"/>
<parameter name="#log_thread" layout="${threadid}"/>
<parameter name="#log_exception" layout="${exception}"/>
<parameter name="#log_stacktrace" layout="${stacktrace}"/>
</target>
and c# code and i dont know is it necessary:
Logger loggerClass = LogManager.GetCurrentClassLogger();
GlobalDiagnosticsContext.Set("steps_guid", steps_guid);
return loggerClass;
and i use it like this :
public bool Login(Entity.USERS user)
{
try
{
this.PageRepository = new xxx.Business.UserBusiness();
logger.Info("User service's instance created");
return this.PageRepository.Login(user);
}
catch (Exception ex)
{
logger.ErrorException("User services login Error", ex);
return false;
}
}
For some reason I get errors while using Diagnostics in Azure. The code of my (WCF) WebRole is:
public override bool OnStart()
{
// To enable the AzureLocalStorageTraceListner, uncomment relevent section in the web.config
DiagnosticMonitorConfiguration diagnosticConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
diagnosticConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
diagnosticConfig.Directories.DataSources.Add(AzureLocalStorageTraceListener.GetLogDirectory());
diagnosticConfig.Directories.BufferQuotaInMB = 256;
// Start diagnostics
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", diagnosticConfig);
// Write trace line
Trace.WriteLine("CUSTUM TRACE MESSAGE");
// Start instance
return base.OnStart();
}
My Web.config file looks like this:
<?xml version="1.0"?>
<configuration>
<configSections>
</configSections>
<system.diagnostics>
<sharedListeners>
<add name="AzureLocalStorage" type="WCFServiceWebRole1.AzureLocalStorageTraceListener, WCFServiceWebRole1"/>
</sharedListeners>
<sources>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing">
<listeners>
<add name="AzureLocalStorage"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
<listeners>
<add name="AzureLocalStorage"/>
</listeners>
</source>
</sources>
<trace autoflush="true">
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
In the Compute Emulator I see the following error:
[MonAgentHost] Output: Monitoring Agent Started
[Diagnostics]: Starting configuration channel polling
[MonAgentHost] Error: MA EVENT: 2012-06-06T10:01:20.111Z
[MonAgentHost] Error: 2
[MonAgentHost] Error: 6396
[MonAgentHost] Error: 6624
[MonAgentHost] Error: NetTransport
[MonAgentHost] Error: 0
[MonAgentHost] Error: x:\btsdx\215\services\monitoring\shared\nettransport\src\xblobconnection.cpp
[MonAgentHost] Error: XBlobConnection::PutBytesXBlob
[MonAgentHost] Error: 1621
[MonAgentHost] Error: ffffffff80050023
[MonAgentHost] Error: 0
[MonAgentHost] Error:
[MonAgentHost] Error: Failed to send bytes to XContainer wad-tracefiles
This error repeats several times. The "wad-tracefiles" container is added by the following code in the AzureLocalStorageTraceListener class:
public static DirectoryConfiguration GetLogDirectory()
{
DirectoryConfiguration directory = new DirectoryConfiguration();
directory.Container = "wad-tracefiles";
directory.DirectoryQuotaInMB = 10;
directory.Path = RoleEnvironment.GetLocalResource("WCFServiceWebRole1.svclog").RootPath;
return directory;
}
Why does writing trace messages fails in this scenario? When I look in my Storage with the Azure Storage Explorer the only table I see is the WADDirectoriesTable and not the the WADLogsTable. The "wad-tracefiles" blob does get created but that is not the place where I should find the Trace messages from my code.
Anyone, any idea? Any help is appreciated!
Your first problem is that you haven't used SetCurrentConfiguration() with your GetDefaultInitialConfiguration() to finally save the transfer time and log level. You must use the set of these API as below:
GetDefaultInitialConfiguration()
SetCurrentConfiguration()
OR
GetCurrentConfiguration()
SetCurrentConfiguration()
Because of it the following line based configuration will not be saved in Diagnostics configuration:
diagnosticConfig.Directories.DataSources.Add(AzureLocalStorageTraceListener.GetLogDirectory());
Use above suggestion and then see what happens.
I would also suggest to just create a very simple web or worker role hello world sample and add general TRACE Message by enabling Azure Diagnostics to see if that give you any error. This will prove if you have any issue with your SDK installation or Azure Storage Emulator or not as well.
Thank you for your reply! The project I am using is a really simple WebRole with only one trace message so I can not strip any code out.
I tried your suggestion and you are right, I do not get any error messages anymore with the following code:
public override bool OnStart()
{
setDiagnostics();
Trace.WriteLine("CUSTUM TRACE MESSAGE");
// Start instance
return base.OnStart();
}
private void setDiagnostics()
{
// Get diagnostics connectionstring
string wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
// Get the diagnostics configuration of the deployment and its role instances that are currently running
DeploymentDiagnosticManager deploymentDiagnosticManager = new DeploymentDiagnosticManager(cloudStorageAccount, RoleEnvironment.DeploymentId);
RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = cloudStorageAccount.CreateRoleInstanceDiagnosticManager(
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
// Load diagnostics configuration
DiagnosticMonitorConfiguration diagConfig = roleInstanceDiagnosticManager.GetCurrentConfiguration();
// Get the default value if there is no config yet
if (diagConfig == null)
diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
// Enable EventLogs
diagConfig.WindowsEventLog.DataSources.Add("Application!*");
diagConfig.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1D);
diagConfig.WindowsEventLog.BufferQuotaInMB = 128;
// Failed Request Logs
diagConfig.Directories.DataSources.Add(AzureLocalStorageTraceListener.GetLogDirectory());
diagConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1D);
diagConfig.Directories.BufferQuotaInMB = 128;
// Crash Dumps
CrashDumps.EnableCollection(true);
// Set new configuration
roleInstanceDiagnosticManager.SetCurrentConfiguration(diagConfig);
// Start the DiagnosticMonitor
DiagnosticMonitor.Start(wadConnectionString, diagConfig);
}
When I look in which tables are present in the Azure Storage Explorer I only see the "WADDirectoriesTable" and the "WADWindowsEventLogsTable". Trace messages should come in the "WADLogsTable" right? So I see the Trace message in the Compute Emulator but I do not see them in my storage... any ideas why?