Meu aplicativo está gravando logs em um diretório, que é "Logs" codificado e está presente no diretório de tempo de execução do meu aplicativo.
Hoje um cliente me perguntou se era possível ter esses logs em outro local (em outro computador).
Como primeiro teste, tentei criar um link simbólico:
- Parei o aplicativo.
- Eu removi o diretório "Logs".
- Usando um WSL no meu computador, criei um link simbólico, algo como
ln -s /mnt/c/Temp_Folder/TestLog/ /mnt/c/<Application>/Logs
. - Eu iniciei meu aplicativo.
Não vi nenhum log aparecendo no diretório C:\Temp_Folder\TestLog\
.
Vejo diferentes razões:
- Ou é uma ideia completamente estúpida tentar usar a tecnologia Linux em um computador Windows.
- Pode funcionar, mas algumas coisas extras precisam ser levadas em consideração.
Espero que seja a segunda opção, mas nesse caso, o que preciso levar em consideração?
Edite após a resposta de Harry
:
Por que usar WSL ln -s
se você pode usar a tecnologia Windows, como mklink
? :-)
Gosto da ideia, mas infelizmente parece não estar funcionando, como você pode ver nas seguintes experiências:
C:\<Runtime_Dir>mklink /D Logs E:\TestLog\
=> result:
29/03/2024 08:21 <SYMLINKD> Logs [E:\TestLog\]
=> Então, de fato, o Logs
link simbólico do diretório é criado, mas quando eu inicio meu aplicativo, ele parece não gravar mais nenhum log (eu os vejo sendo criados em uma janela do console, mas eles não são gravados em um arquivo).
Algumas outras experiências: (Lembro-me de algo sobre um cruzamento de antes, mas os detalhes escaparam da minha mente)
C:\<Runtime_Dir>mklink /D /J Logs E:\TestLog\
Local volumes are required to complete the operation.
C:\<Runtime_Dir>mklink /D /H Logs E:\TestLog\
The system cannot find the path specified.
C:\<Runtime_Dir>mklink /J Logs E:\TestLog\
Local volumes are required to complete the operation.
Edit2 depois de mais algumas experiências:
Parece não funcionar ao me referir a outra unidade, mas parece funcionar quando me refiro a outro diretório no mesmo computador, como você pode ver aqui:
C:\<Runtime_Dir>mklink /D Logs C:\Temp_Folder\TestLog\
symbolic link created for Logs <<===>> C:\Temp_Folder\TestLog\
C:\<Runtime_Dir>mklink /D /J Logs C:\Temp_Folder\TestLog\
Junction created for Logs <<===>> C:\Temp_Folder\TestLog\
Posso confirmar que, em ambos os casos, os logs estão sendo criados!
Em outras palavras, o problema não é que o link simbólico/junção do Windows não esteja funcionando: o problema está no fato de o link simbólico/junção estar se referindo a outra unidade.
Lembro que existem duas, até três maneiras de criar um drive no Windows (um mapeamento de drive, um subst (?) e outro (???), isso tudo está muito embaçado na minha cabeça), e estou pensando se a história do link simbólico/junção pode estar funcionando em um tipo de unidade, mas não no outro, e se há uma maneira de contornar isso.
Edit3 após a resposta de u1686_gravity :
Mesmo usando o caminho UNC e tendo o comportamento configurado "correto", ainda parece não funcionar:
fsutil behavior query symlinkEvaluation
Local to local symbolic links are enabled.
Local to remote symbolic links are enabled. => That's the one, isn't it?
Remote to local symbolic links are disabled.
Remote to remote symbolic links are disabled.
C:\<Runtime_Dir>mklink /D Logs \\petrvs01\Log\TestLog\
symbolic link created for Logs <<===>> \\petrvs01\Log\TestLog\
O link é criado, mas nenhum arquivo de log está sendo criado ali.
Então, como acho que estou no caminho certo aqui, resolvi fazer outro teste: usar o Windows Explorer para entrar no Logs
diretório/symlink/junction e criar um arquivo de texto simples, usando o menu de contexto do explorer. Isso não funciona devido à seguinte mensagem de erro:
Aprendi três coisas até agora:
- Para criar um link simbólico no Windows, use
mklink
em vez do WSLln -s
. Abra um prompt de comando como administrador para isso. - Para criar um link simbólico/junção para um diretório remoto, você precisa usar o caminho UNC, não a letra da unidade.
- A permissão para criar links simbólicos/junções de e para diretórios remotos é verificada, usando o
fsutil
comandofsutil behavior query symlinkEvaluation
.
A próxima coisa que preciso aprender: onde verificar as permissões de destino do link simbólico/junção? Alguém tem uma ideia?
Os links simbólicos no Linux são implementados de maneira diferente do Windows:
Isso significa que links simbólicos (ou links simbólicos) criados por meio do Windows Subsystem for Linux (WSL) não podem ser seguidos pelo Windows.
O Windows cria links simbólicos usando o comando mklink .
Para obter mais informações, consulte o artigo
O guia completo para a criação de links simbólicos (também conhecidos como links simbólicos) no Windows .
Para o problema de "Acesso negado", cito a postagem criando links simbólicos na unidade de rede, parte da resposta de GambleNerd :
É possível, mas você precisa usar caminhos UNC em vez de letras de unidade, já que estas últimas não são necessariamente globais – embora os volumes físicos tenham atribuições globais, cada sessão de logon pode ter seus próprios mapeamentos privados (por exemplo, o usuário 1 pode ter Y :\representando um local e o usuário 2 pode representar outro). Pense nisso como se cada usuário tivesse seu próprio "namespace de montagem" no Linux (pam_namespace).
Especificamente, todas as letras de unidade de "compartilhamento de rede mapeada" são privadas para sua sessão de logon e não serão compreendidas no contexto do kernel quando o link simbólico for seguido. Portanto, se o destino estiver em outra máquina, você precisará usar o caminho UNC bruto para ele:
Você também deve certificar-se de que a avaliação do link simbólico local para remoto não tenha sido desativada por meio do
fsutil behavior query symlinkEvaluation
.Execute
icacls
no alvo – ou clique com o botão direito no Explorer e vá em "Propriedades > Segurança".Além disso, links simbólicos e junções no Windows podem ter suas próprias permissões, que podem ser verificadas usando
icacls Logs /l
. Duvido que esse seja o problema, já que o link inicialmente herdaria as mesmas permissões que um diretório normal herdaria – mas pode valer a pena verificar.Portanto, primeiro certifique-se de que a criação de arquivos/pastas funcione sem o envolvimento de links simbólicos, ou seja, diretamente através do caminho UNC (ou de uma unidade mapeada, sem diferença), e somente depois de fazer isso funcionar, tente fazer o mesmo através de um link simbólico.
Não esqueça que se seu aplicativo estiver rodando como um serviço, com credenciais próprias (conta de serviço), então as permissões deverão ser concedidas a essa conta; se estiver sendo executado como "NetworkService", as permissões deverão ser concedidas à conta da máquina (FOOBAR$). (E se estiver sendo executado como "LocalService", nunca terá acesso ao compartilhamento de rede.)